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

20

我遇到了这个错误:

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个回答

20
为避免这个错误,你应该用像{0,10}这样的区域替换+
([a-z])(?!.*\1)(?<!\1.{0,10})([a-z])(?!.*\2)(?<!\2.{0,10})(.)(\3)(.)(\5)

我之前使用的是这个 (?<=(OF[ ]{0,5})|(MIRS[ ]{0,5}))[0-9]+,但是它一直报错。错误信息是“Look-behind group does not have an obvious maximum length near index 22”。后来看了你的评论,我把 * 改成了 {0,5},然后就完美地解决了问题。不知道为什么 Java 不支持这个。 - shabby
总的来说,这是一种有点不太正规的解决方法,但是如果可以保证该部分不会太长,只需将“+”替换为类似于“{1,999}”之类的内容即可。 - Nyerguds
请注意,如果您要替换一个 +,应该从最小值 1 开始,而不是 0。 - Nyerguds

13

Java不支持后顾的可变长度。
在这种情况下,如果你的整个输入是一个单词,似乎可以很容易地忽略它:

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

两个断言都没有增加任何内容:第一个断言至少需要两个字符,而你只有一个字符;而第二个检查第二个字符与第一个不同,这已经被(?!.*\1)所覆盖。

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


2
Java 不支持“可变长度”的后向引用正则表达式这种说法可能不正确。例如,以下正则表达式可以正常工作:(?<=(a*))afs - Rocky Inde

5

Java通过允许有限重复来进一步发展。你仍然不能使用星号或加号,但是可以使用问号和大括号并指定最大参数。Java确定了回顾的最小和最大可能长度。
正则表达式(?<!ab{2,4}c{3,5}d)test中的回顾有6种可能的长度。它可以在7到11个字符之间。当Java(版本6或更高版本)尝试匹配回顾时,它首先向字符串中后退最少数量的字符(在此示例中为7),然后像往常一样从左到右评估回顾内部的正则表达式。如果失败,Java会再向后退一个字符并重试。如果回顾继续失败,Java将继续向后退,直到回顾匹配或者向后退了最大数量的字符(在这个例子中为11)。当回顾的可能长度增加时,这种重复的向后退会影响性能。请记住这一点。不要选择任意大的最大重复次数来解决回顾内缺乏无限量词的问题。Java 4和5存在错误,导致在某些情况下具有交替或可变量词的回顾失败,但这些错误已在Java 6中得到修复。

这里复制


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接