PHP preg_match_all与所有内容都不匹配

时间:2016-03-23 20:16:54

标签: php regex preg-match preg-match-all

请考虑以下代码段:

$example = "DELIM1test1DELIM2test2DELIM1test3DELIM2test4"; // and so on

preg_match_all('/DELIM1(.*?)DELIM2(.*?)/', $example, $matches);

$matches数组变为:

array:3 [
  0 => array:2 [
    0 => "DELIM1test1DELIM2"
    1 => "DELIM1test3DELIM2"
  ]
  1 => array:2 [
    0 => "test1"
    1 => "test3"
  ]
  2 => array:2 [
    0 => ""
    1 => ""
  ]
]

正如您所看到的,它无法获得test2test4。出现这种情况的原因和可能的解决方案是什么?谢谢。

5 个答案:

答案 0 :(得分:3)

.*?不贪心;如果你之后没有约束,它将匹配必要的最小值:零个字符。你需要一个约束来强迫它匹配更多。例如:

/DELIM1(.*?)DELIM2(.*?)(?=DELIM1|$)/

答案 1 :(得分:3)

preg_split会更好:

$example = "DELIM1test1DELIM2test2DELIM1test3DELIM2test4"; // and so on
$keywords = preg_split("/DELIM1|DELIM2/", $example,0,PREG_SPLIT_NO_EMPTY);
print_r($keywords);

输出:

Array
(
    [0] => test1
    [1] => test2
    [2] => test3
    [3] => test4
)

演示:http://ideone.com/s5nC0k

答案 2 :(得分:2)

模式结尾处的懒惰子模式匹配0(*?)或1(+?)个字符,因为它们匹配的数量尽可能少。

你仍然可以使用延迟匹配并追加一个前瞻,它需要DELIM1出现在字符串的值或结尾之后:

/DELIM1(.*?)DELIM2(.*?)(?=$|DELIM1)/

demotempered greedy tokenDELIM1(.*?)DELIM2((?:(?!DELIM1).)*) - demo)在性能方面非常接近。

然而,最好的方法是展开它:

DELIM1(.*?)DELIM2([^D]*(?:D(?!ELIM1)[^D]*)*)

请参阅another demo

答案 3 :(得分:2)

这些值是您的锚点的外部,因此它们不会匹配。例如(有一些额外的空格)

str:  DELIM1  test1  DELIM2         test2   DELIM1  test3  DELIM2        test4
pat:  DELIM1  (.*?)  DELIM2  (.*?)          DELIM1  (.*?)  DELIM2 (.*?) 
             match #1                                match #2

(.*?)是非贪婪的匹配,可以/将匹配0长度的字符串。由于M2te之间的边界是一个0长度的字符串,因此该不可见的零长度字符匹配,并且该模式在那里终止。

答案 4 :(得分:0)

您可以使用此负前瞻性正则表达式:

preg_match_all('/DELIM1((?:(?!DELIM1|DELIM2).)*)DELIM2((?:(?!DELIM1|DELIM2).)*)/',
                $example, $matches);

(?:(?!DELIM1|DELIM2).)*将匹配在下一个位置没有DELIM1DELIM2的任何字符中的0个或更多。

<强>输出:

print_r($matches);

    Array
    (
        [0] => Array
            (
                [0] => DELIM1test1DELIM2test2
                [1] => DELIM1test3DELIM2test4
            )

        [1] => Array
            (
                [0] => test1
                [1] => test3
            )

        [2] => Array
            (
                [0] => test2
                [1] => test4
            )        
    )