2011-10-24 179 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