2011-10-24 103 views
1

我尝试在PHP中使用正则表达式匹配字符串中的两个部分。我想,贪婪是有问题的。我希望第一个正则表达式(参见注释)给我前两个捕获,作为第二个正则表达式,但仍然捕获这两个字符串。我究竟做错了什么?正则表达式不匹配,贪婪

我试图获得+123(如果cd:存在,如在第一个字符串中)和456

<?php 

$data[] = 'longstring start waste cd:+123yz456z longstring'; 
$data[] = 'longstring start waste +yz456z longstring'; 
$regexs[] = '/start[^z]*?(cd:([^y]+)y)?[^z]*z([^z]*)z/'; // first 
$regexs[] = '/start[^z]*?(cd:([^y]+)y)[^z]*z([^z]*)z/'; // second 

foreach ($regexs as $regex) { 
    foreach ($data as $string) { 
    if (preg_match($regex, $string, $match)) { 
     echo "Tried '$regex' on '$string' and got " . implode(',', array_split($match, 1)); 
     echo "\n"; 
    } 
    } 
} 
?> 

输出是:

Tried '/start[^z]*?(cd:([^y]+)y)?[^z]*z([^z]*)z/' on 'longstring start waste cd:+123yz456z longstring' and got ,,456 
Tried '/start[^z]*?(cd:([^y]+)y)?[^z]*z([^z]*)z/' on 'longstring start waste +yz456z longstring' and got ,,456 
Tried '/start[^z]*?(cd:([^y]+)y)[^z]*z([^z]*)z/' on 'longstring start waste cd:+123yz456z longstring' and got cd:+123y,+123,456 

没有第四行因为cd:不存在的第二串英寸

预期输出(因为我不是专家),其中第一行从实际输出的区别:

Tried '/start[^z]*?(cd:([^y]+)y)?[^z]*z([^z]*)z/' on 'longstring start waste cd:+123yz456z longstring' and got cd:+123y,+123,456 
Tried '/start[^z]*?(cd:([^y]+)y)?[^z]*z([^z]*)z/' on 'longstring start waste +yz456z longstring' and got ,,456 
Tried '/start[^z]*?(cd:([^y]+)y)[^z]*z([^z]*)z/' on 'longstring start waste cd:+123yz456z longstring' and got cd:+123y,+123,456 
+0

看起来你忘了行输出的。 – Chriszuma

+2

另外,你能用文字解释你试图捕捉什么吗?这不是很明显。 – Chriszuma

+0

@Chriszuma第二个正则表达式与第二个字符串不匹配,因为该字符串中不存在“cd:”。 – bloodphp

回答

1

好了,你想捕捉+123如果有cd:,始终456?这是我会怎么做:

$data[] = 'longstring start waste cd:+123yz456z longstring'; 
$data[] = 'longstring start waste +yz456z longstring'; 

$regexs[] = '/start.+?(?:cd:(.+?)y)?.*?z(.+?)z/'; 

与自由使用非贪婪(?)乘法器,你可以得到它做你想要什么。

另请注意(?:)非捕获组。它们非常有用。

编辑显然不起作用,让我们尝试了不同的方法,用“要么/或”组:

$regexs[] = '/start.+?(?:cd:(.+?)yz(.+?)z|\+yz(.+?)z)/'; 
+0

非常感谢您的回复。 对于你的正则表达式:'尝试'/start.+?(?:cd:(.+?)y)?.*?z(.+?)z/'on'longstring start waste cd:+ 123yz456z longstring'and得到,456' 它似乎没有捕获'+ 123'由一些未知的原因。 – bloodphp

+0

感谢您提供关于'(?:)'的提示。太酷了! (不知道这是可能的。) – bloodphp

+0

好吧,我不明白为什么这不起作用,但我编辑我的答案尝试不同的方式。 – Chriszuma