2011-01-19 92 views
2

怎麼來的Java(使用Matcher.find())沒有找到可能的最長匹配?java的正則表達式沒有找到最長匹配

regex = "ab*(bc)?" 

隨着輸入「abbbc」,正則表達式找到「abbb」,而不是「abbbc」,它也匹配並且更長。 有沒有辦法強制它匹配最長的字符串?

回答

1

的部分匹配貪婪地從左到右。所以b*貪婪地匹配,導致(bc)?失敗,這很好,所以匹配器永遠不會回退嘗試更短的b*

也許ab*?(?:(?![bc])|(bc))你想要做什麼。

+0

感謝您的幫助,但這似乎有同樣的問題,因爲它僅返回「A」。 (然而「abbbc」匹配??)我基本上尋找一種方法來獲得一個可選的子字符串(例如「bc」),並強制它將它包含在匹配項中(如果它存在的話)。 – 2011-01-19 18:21:29

+0

@steve李,這是我的愚蠢。我更新了正則表達式。 – 2011-01-19 18:24:19

5

的(BC)是一個確切的字符串,它沒有被發現,因爲b *爲貪心,但因爲(BC)?
是可選的,在最後'b'後匹配成功。 你可能想要的東西是這樣的:ab*[bc]?,但這個doesent有道理,所以可能ab*c?。如果這個正則表達式代表更精細的東西,你應該發佈這些例子。

這裏是正則表達式引擎是如何看待它:

Compiling REx "ab*(bc)?" 
Matching REx "ab*(bc)?" against "abbbc" 
    0 <> <abbbc>    | 1:EXACT <a>(3) 
    1 <a> <bbbc>    | 3:STAR(6) 
            EXACT <b> can match 3 times out of 2147483647... 
    4 <abbb> <c>    | 6: CURLYM[1] {0,1}(16) 
    4 <abbb> <c>    | 10: EXACT <bc>(14) 
             failed... 
            CURLYM trying tail with matches=0... 
    4 <abbb> <c>    | 16: END(0) 
Match successful! 

Compiling REx "ab*[bc]?" 
Matching REx "ab*[bc]?" against "abbbc" 
    0 <> <abbbc>    | 1:EXACT <a>(3) 
    1 <a> <bbbc>    | 3:STAR(6) 
            EXACT <b> can match 3 times out of 2147483647... 
    4 <abbb> <c>    | 6: CURLY {0,1}(19) 
            ANYOF[bc] can match 1 times out of 1... 
    5 <abbbc> <>    | 19: END(0) 
Match successful! 
1

其他有助於提高正則表達式;但僅僅強調答案是「因爲它確實貪婪匹配」。也就是說,你得到的匹配是它根據算法達到的匹配(從左到右基本上是最長的子匹配)。

1

如果表達式實際上看起來是這樣,你不關心分組,它可以改寫爲ab+c?

如果表達實際上是更爲複雜和具有(bc)是必不可少的,你也可以使用負前瞻如下,我認爲這將是比邁克薩穆埃爾的解決方案更優雅:ab*(?!c)(bc)?