简体   繁体   English

正则表达式,多次出现

[英]Regex, get multiple occurrences

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. 如果我只有1,它会工作,但是如果我有1,它将不能返回正确的值。 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. 但是,我现在尝试添加elsif参数,但无法使其正常工作。 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. 它具有许多无用的元素,例如[0] [4]等。

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 ,而不仅仅是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
    )

The answers pointing out that you should use preg_match_all are correct. 指出应该使用preg_match_all的答案是正确的。

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 (ie lazy): 这将导致它在一次匹配中同时匹配两个标签,因此您需要使星星不贪心 (即懒惰):

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

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. char并使用preg_match_all()函数。

Use a non-greedy match .*? 使用非贪婪匹配.*? and preg_match_all for this purpose. preg_match_all为此。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM