2013-08-25 16 views
1

我需要指定一個首選的可選子模式,但允許備份。不幸的是,這兩種模式都是共享模式的一部分,而首選的匹配是在之後。例如:指定優先子模式在正則表達式

$string = "Fuzzy bunny is bald"; 
preg_match_all('@(?:bunny is (\w+)|(\w+) bunny)@',$string,$result); 

預期的行爲是隻匹配「光頭」,除非它不能,在這種情況下,它應該匹配「模糊」,然而,因爲它首先遇到具有「模糊」它的反向匹配。

感謝您的幫助。

回答

2

想通了。必須在首選子模式內指定非偏好的捕獲部分,而不捕獲它,以便它可以同時看到它們。然後按首選順序列出它們。例如:

'@(?:\ w +兔子是(\ w +)|(\ w +)兔子)@'

+0

或者,您可以在'^。*'前加上已有的模式(或者兩個選項)。這將是一個更普遍的解決方案,並且還可以用於像「兔子禿頭」(根本沒有「模糊」)的輸入。 –

+0

+1比我的t好多[瘋狂的解決方案] –

+0

爲了僅匹配字母數字字符並忽略它中是否有數字,你可以這樣做。 '@(?:[a-zA-Z] +兔子是([a-zA-Z] +)|([a-zA-Z] +)兔子)@' – hwnd

0

你可以試試這個:

$strings = array("Fuzzy bunny is bald", "Fuzzy bunny is"); 
$pattern = '~(?J)^(?(?=^[^b]*+bunny is \w++)^[^b]+bunny is (?<word>\w++)|(?<word>\w++) bunny)~'; 
foreach ($strings as $k => $string) { 
    if (preg_match($pattern, $string, $match)) 
     echo "<br/>string$k : " . $match['word'] . "\n"; 
} 

或本:

$pattern='~(?|(\w++) si ynnub|ynnub (\w++))~'; 
foreach ($strings as $k => $string) { 
    if (preg_match($pattern, strrev($string), $match)) 
     echo "<br/>string$k : " . strrev($match[1]) . "\n"; 
}