Java正则表达式错误 - 后瞻组没有明显的最大长度

时间:2011-09-25 04:59:04

标签: java regex lookbehind

我收到此错误:

java.util.regex.PatternSyntaxException: Look-behind group does not have an
    obvious maximum length near index 22
([a-z])(?!.*\1)(?<!\1.+)([a-z])(?!.*\2)(?<!\2.+)(.)(\3)(.)(\5)
                      ^

我正在尝试匹配COFFEE,但不是BOBBEE

我正在使用java 1.6。

3 个答案:

答案 0 :(得分:15)

要避免此错误,您应该将+替换为{0,10}这样的区域:

([a-z])(?!.*\1)(?<!\1.{0,10})([a-z])(?!.*\2)(?<!\2.{0,10})(.)(\3)(.)(\5)

答案 1 :(得分:8)

Java不支持后面的变长。
在这种情况下,您似乎可以轻松忽略它(假设您的整个输入是一个单词):

([a-z])(?!.*\1)([a-z])(?!.*\2)(.)(\3)(.)(\5)

两个lookbehinds都不添加任何东西:第一个断言至少两个字符,你只有一个,第二个字符检查第二个字符与第一个字符不同,(?!.*\1)已经覆盖了第一个字符。

工作示例:http://regexr.com?2up96

答案 2 :(得分:4)

  

Java通过允许有限重复更进一步。您仍然无法使用星号或加号,但您可以使用问号和带有指定max参数的花括号。 Java确定了lookbehind的最小和最大可能长度。
正则表达式(?<!ab{2,4}c{3,5}d)test中的后视有6种可能的长度。它可以是7到11个字符长。当Java(版本6或更高版本)尝试匹配lookbehind时,它首先返回字符串中的最小字符数(本例中为7),然后像往常一样从左到右计算lookbehind内的正则表达式。如果失败,Java会再退一个字符并再次尝试。如果lookbehind继续失败,Java继续退回,直到lookbehind匹配或者它已经退回最大字符数(在本例中为11)。当看后方的可能长度的数量增加时,重复踩回主题串会杀死性能。记住这一点。不要选择任意大的最大重复次数来解决lookbehind中缺少无限量词的问题。 Java 4和5有一些错误,当它在某些情况下成功时会导致交替或变量量词的后观失败。这些错误在Java 6中得到修复。

Here

复制