2011-01-19 36 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)?