Java中存在明显的Look-behind组最大长度

时间:2009-12-28 21:30:35

标签: java regex

在这个Java代码中:

public class Main {
  public static void main(String[] args) {
    "".matches("(?<!((.{0,1}){0,1}))");
  }
}

编译器(我正在使用JVM 1.6.0_17-b04)喊“异常......后视组没有明显的最大长度”。我看到here

  

Java通过允许有限重复更进一步。您仍然无法使用星号或加号,但您可以使用问号和带有指定max参数的花括号。 Java认识到有限重复可以被重写为具有不同但固定长度的字符串的交替。

但是......在上面的代码中有非常明显的有限最大长度 - 1(简单产品)。

当然,真正的问题是更复杂的模式,例如:

(?<!bad(\s{1,99}(\S{1,99}\s{1,99}){0,6}))good

(好的,在7字的范围内,背后没有坏词)。

我该如何解决?

1 个答案:

答案 0 :(得分:3)

如果你从负面的后卫中删除捕获组,那么它似乎是编译的。我甚至不确定意图是什么,或者捕获组应该在负面观察中做些什么。这是故意的吗?

编辑以澄清:

你写了正则表达式:

"(?<!((.{0,1}){0,1}))"

"(?<!"部分表示负面的后视,因为您想要找到此之前发生的匹配。然而,它充满了捕获群体......即:所有裸体()。这没有任何意义,因为那些不可能捕获任何东西,因为它背后是负面的。 (如果您不熟练使用正则表达式,则在匹配发生后,捕获组将用于提取匹配的特定子范围。)

取出所有这些括号,你将不再收到错误......更不用说它们是不必要的了:

"(?<!.{0,1}{0,1})"

例如,上述部分可以正常工作。如果你真的需要在负面看后面的括号,那么你应该使用非捕获组,如“(?:mypattern)”。在这个简单的例子中,他们不会为你做任何事情,双{0,1}有点多余。

编辑2:

所以我试图让你的更复杂的例子工作,甚至切换到非捕获组也没有摆脱Java正则表达式的混乱。解决它的唯一方法似乎是按照评论中的建议摆脱{0,6}。

例如,这将编译:

"(?<!bad(?:\\s{1,99}(?:\\S{1,99}\\s{1,99})?(?:\\S{1,99}\\s{1,99})?(?:\\S{1,99}\\s{1,99})?(?:\\S{1,99}\\s{1,99})?(?:\\S{1,99}\\s{1,99})?(?:\\S{1,99}\\s{1,99})?))good"

......并且做同样的事情但是它更加丑陋。

这可能是正则表达式不是完整答案的情况,而只是需要多次传递的更大解决方案的一部分。