java正则表达式找不到最长匹配项

java正则表达式找不到最长匹配项,java,regex,Java,Regex,为什么java(使用Matcher.find())找不到最长的匹配 regex = "ab*(bc)?" 通过输入“abbbc”,正则表达式会找到“abbb”,而不是“abbbc”,后者也匹配并且更长。 有没有办法强迫它匹配尽可能长的字符串?这些部分从左到右非常匹配。因此,b*贪婪地匹配,这会导致(bc)?失败,这很好,因此匹配者从不回溯尝试更短的b* 也许ab*?(?:(?![bc])|(bc))做了你想做的。这个(bc)是一个精确的字符串,没有找到它,因为b*是贪婪的,但是因为(bc) 在

为什么java(使用Matcher.find())找不到最长的匹配

regex = "ab*(bc)?"
通过输入“abbbc”,正则表达式会找到“abbb”,而不是“abbbc”,后者也匹配并且更长。
有没有办法强迫它匹配尽可能长的字符串?

这些部分从左到右非常匹配。因此,
b*
贪婪地匹配,这会导致
(bc)?
失败,这很好,因此匹配者从不回溯尝试更短的
b*

也许
ab*?(?:(?![bc])|(bc))
做了你想做的。

这个(bc)是一个精确的字符串,没有找到它,因为b*是贪婪的,但是因为(bc)
在最后一个“b”之后成功匹配是可选的。 你可能想要这样的东西:
ab*[bc]?
但是这没有意义,所以可能
ab*c?
。如果这个正则表达式表示更详细的内容,您应该发布这些示例

以下是regex引擎的看法:

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!
编译REx“ab*(bc)?”
匹配REx“ab*(bc)?”与“abbbc”
0 | 1:精确(3)
1 | 3:星(6)
精确匹配2147483647中的3次。。。
4 | 6:CURLYM[1]{0,1}(16)
4 | 10:精确(14)
失败。。。
CURLYM正在尝试匹配项为0的尾部。。。
4 | 16:结束(0)
比赛成功!
编译REx“ab*[bc]?”
匹配REx“ab*[bc]?”和“abbbc”
0 | 1:精确(3)
1 | 3:星(6)
精确匹配2147483647中的3次。。。
4 | 6:CURLY{0,1}(19)
任何[bc]都可以匹配1次中的1次。。。
5 | 19:结束(0)
比赛成功!

其他人帮助改进了regexp;但要强调的是,答案是“因为它确实存在贪婪匹配”。也就是说,您得到的匹配是它根据算法达到的匹配(基本上是从左到右进行最长的子匹配)。

如果您的表达式看起来确实如此,并且您不关心分组,则可以将其重写为
ab+c?


如果表达式实际上更复杂,并且有
(bc)
是必要的,那么您可以使用如下的反向前瞻,我认为它比Mike Samuel的解决方案更优雅:
ab*(?!c)(bc)?

谢谢您的帮助,但这似乎有相同的问题,因为它只返回“a”。(然而“abbbc”匹配???)我基本上是在寻找一种方法来拥有一个可选的子字符串(例如“bc”),并强制它在匹配中包含它(如果它存在)。@steve lee,我太傻了。我更新了正则表达式,在这种情况下有效。谢谢我想知道如何将其应用于以下类似的正则表达式:“[a-z][a-z]*(?!St\)(St\)?”即:以字母开头,后跟一个或多个字母。字符串要么不包含句点,要么包含“St.”。它需要包含“St”。如果它存在。在您的解决方案中,为什么贪婪的“*”不消耗所有的b给予abbb(与“ab*(bc)”相同)。如何添加否定的前瞻性使它考虑“BC”?(但是没有它“bc”比赛就失败了?)谢谢你的帮助@steve lee,(!c)不会让a'c'跟随a'b',因此它会回溯1个角色,以便b*看到a'b'超越自身。满足(??c),然后匹配在最后的“BC”上匹配(BC)?@史提夫:<代码> [AZ]([Z])(St..)/代码>应该是因为“代码> S/<代码>不匹配<代码> [AZ] < /代码>,不是吗?@史提夫Lee,或者<代码> ^ [AZ]((St..)[AZ])* $ < /代码>如果它在中间。如果是在最后,你允许u/l的情况,那就不同了。