2

I would like to know how to get multiple occurrences from a regex.

$str = "Some validations <IF TEST>firstValue</IF> in <IF OK>secondValue</IF> end of string.";
$do = preg_match("/<IF(.*)>.*<\/IF>/i", $str, $matches);

This is what I've done so far. It works if I have only 1 , but if I have more it doesn't return the right values. Here is the result:

Array ( [0] => firstValue in secondValue [1] => TEST>firstValue in

I need to get the "TEST" and the "OK" values.

EDIT: I've brought the modifications suggested, thanks a lot it works fine ! However, I am now trying to add a elsif parameter and can't get it to work well. Here is what I've done:

$do = preg_match_all("~<IF([^<>]+)>([^<>]+)(</IF>|<ELSEIF([^<>]+)>([^<>]+)</IF>)~", $str, $matches, PREG_SET_ORDER);

and the results is

Array 
( 
    [0] => Array 
           (
              [0] => firstValuesecondValue 
              [1] => TEST 
              [2] => firstValue 
              [3] => secondValue 
              [4] => TEST1 
              [5] => secondValue 
           ) 
    [1] => Array 
           ( 
               [0] => thirdValue 
               [1] => OK 
               [2] => thirdValue 
               [3] => 
           ) 
) 

Is there a way to make my array more clean ? It has many elements which are useless like the [0][4] etc.

4 Answers 4

2

You should make the regex more specific. The .* that you are using should either be less greedy, or better yet disallow other angle brackets:

~<IF([^<>]+)>([^<>]+)</IF>~i

More importantly, you should use preg_match_all, not just preg_match.

preg_match_all("~<IF([^<>]+)>([^<>]+)</IF>~i", $str, $matches, PREG_SET_ORDER);

That'll give you a nested array like:

[0] => Array
    (
        [0] => <IF TEST>firstValue</IF>
        [1] =>  TEST
        [2] => firstValue
    )

[1] => Array
    (
        [0] => <IF OK>secondValue</IF>
        [1] =>  OK
        [2] => secondValue
    )
Sign up to request clarification or add additional context in comments.

Comments

1

The answers pointing out that you should use preg_match_all are correct.

But there is another problem: the .* is greedy by default. This will cause it to match both tags in a single match, so you need to make the star non-greedy (i.e. lazy):

/<IF(.*?)>.*?<\/IF>/i

Comments

1

Use this code:

$string = "Some validations <IF TEST>firstValue</IF> in <IF OK>secondValue</IF> end of string.";
$regex = "/<IF (.*?)>.*?<\/IF>/i";
preg_match_all($regex, $string, $matches);
print_r($matches[1]);

You regex is good but you have to use the non-greedy mode adding the ? char and use the preg_match_all() function.

Comments

0

Use a non-greedy match .*? and preg_match_all for this purpose.

Comments

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.