在这个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字的范围内,背后没有坏词)。
我该如何解决?
答案 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"
......并且做同样的事情但是它更加丑陋。
这可能是正则表达式不是完整答案的情况,而只是需要多次传递的更大解决方案的一部分。