2012-07-21 259 views
2

a *表示零個或多個a。正則表達式問題與ab * a

在字符串'abbabba'中,我們有兩個abba。 (abba)bba和abb(abba)。 preg_match_all僅匹配第一個匹配項。

我是否缺少任何基本的正則表達式基礎?

$string = 'abbabba'; 

preg_match_all("/ab*a/", $string, $matches); 

print_r($matches); 

Array ([0] => Array ([0] => abba)) 
+0

你可能只是想看看未來在年底'了'並將其添加到稍後您的比賽。 – hakre 2012-07-21 11:25:23

回答

5

subject中搜索pattern給出的正則表達式所有比賽,並把他們在比賽中由標誌指定的順序。

找到第一個匹配後,後續搜索將繼續從上次匹配結束。

Source

+0

感謝RiaD,明白了。 – 2012-07-21 11:22:41

3

因爲ab*a消耗文本。這意味着解析器匹配第一個匹配項abba,並從bba開始,不匹配您的模式。

3

解決方案:與捕獲組一起使用lookahead assertion

preg_match_all('/(?=(ab*a))/', $subject, $result, PREG_PATTERN_ORDER); 
$result = $result[1]; 
+0

很酷。乍一看,我會猜想它是不可能的。每天學些新東西。謝謝! +1 – ridgerunner 2012-07-21 15:58:22

2

*表示貪婪搜索。當引擎看到b*時,它將一直匹配到字符串的末尾並向後移動,直到到達b,然後它會檢查匹配的字符串是否與您的模式匹配。

首先,它看起來與a相匹配,它的作用恰到好處。然後它看到b*,所以它一直匹配字符串,直到字符串中最後一次出現b(因爲*指示b應該匹配'貪婪'),在此時基本匹配abb。然後它會看到它需要匹配另一個a才能成功匹配,因此它會抓取下一個字符a,然後完成,剩下bba,這與您的模式不匹配。希望這可以幫助。

如果你做了什麼歐米茄說你會取得史詩般的勝利。

+3

不,'b *'只能匹配'b',所以一旦它用完'b's就會停止匹配 - 在這種情況下,在下一個'a'處。如果OP使用'。*'而不是'b *',你的話會是真的。但在這種情況下回溯不是問題。 – 2012-07-21 11:53:59

+0

Yuuuuup。我有很多東西要學習...... *嘆氣* – 2012-07-21 12:00:06

2

要找到去的發生次數與:

preg_match_all('/(?=ab*a)/', $input, $result); 
print(count($result[0])); 

要找到匹配,使用:

preg_match_all('/(?=(ab*a))/', $input, $result); 
print_r($result[1]); 
+0

+1,很好。我有很多要學習正則表達式:) – 2012-07-21 11:53:03