1

I have to check several strings...the format of each string could be the following:

I-IVWM_Ask-21_(max_2h)

or

D-7849_DG303_(max_4h)

or

Aliante_Privato

I need to capture text in brackets, first part of string outside brackets and replace underscore with spaces.

I'm tring to use preg_match in PHP, as follow

preg_replace('/\([^)]*\)|[()]/', '', $string);

The code above remove string and brackets but leave underscore and doesn't capture the string inside brackets.

Any help to figure out my issue? Thanks

0

2 Answers 2

2

What you might do is first match the pattern, and for the match replace the parenthesis and underscores with a space using preg_replace_callback.

Pattern to match the strings:

^[^\s()]+(?:\([^()]*\))?$
  • ^ Start of string
  • [^\s()]+ Match 1+ chars other than parenthesis or whitespace chars
  • (?:\([^()]*\))? Optionally match the part between parenthesis
  • $ End of string

Regex demo | Php demo

For example

$strings = [
    "I-IVWM_Ask-21_(max_2h)",
    "D-7849_DG303_(max_4h)",
    "Aliante_Privato"
];

foreach ($strings as $str) {
    $pattern = "/^[^\s()]+(?:\([^()]*\))?$/";
    echo preg_replace_callback($pattern, function ($x) {
        return trim(preg_replace("/[()_]+/", " ", $x[0]));
    }, $str) . PHP_EOL;
}

Output

I-IVWM Ask-21 max 2h
D-7849 DG303 max 4h
Aliante Privato
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks a lot for your help. I'm trying to understand the pattern but it's very criptic to me....is there a way to get back the string splitted in three groups? The first should be the code with a letter, minus sign and four numbers/letters ( D-7849 or I-IVWM, the second shold be the model name ( Ask-21 .. for example ), the last group should be the duration ( max 2h ) Thanks a lot again...still needs to learn a lot about regex...
@Federico Like this? ^([A-Z]-[A-Z0-9]{4})_([A-Za-z0-9]+(?:-[A-Za-z0-9]+)*)_\(([^()]+)\) regex101.com/r/AkPfD6/1 Then you can replace the underscore from the 3rd group using preg_replace_callback as in the example.
Unbelieveble!...the power of regex is incredible. Thanks a lot again for invaluable help!
2
$strings = [
    "I-IVWM_Ask-21_(max_2h)",
    "D-7849_DG303_(max_4h)",
    "Aliante_Privato"
];

$result = array_map('trim', preg_filter('~[_()]+~', ' ', $strings));

3 Comments

Really interesting Casimir…can I ask what’s the purpose of the square bracket? Needs to understand array_map function too
@Federico: square brackets are not different than something like [A-Z], they defines a character class, except that this one doesn't contain a range of letters but only 3 characters (, ), _. array_map applies a function to each item of an array and returns a new array. The applied function is simply trim. Note that this answer has nothing special and the code doesn't check the format, but I wrote it only to show a certain conciseness to treat an array "in one shot". Following the same idea, you can use preg_grep to select items that match the desired format.
Great feedback and support...as usual. Thanks a lot

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.