2009-12-28 85 views
2

向后看组明显最大长度在此Java代码:存在在Java中

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

编译器(我使用JVM 1.6.0_17-B04)呼喊“异常...向后看组没有明显的最大长度“。我看到here即:

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

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

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

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

(不错的话,那有没有不好的话背后,7字范围)。

我该如何解决?

+0

有散步,可以在某些情况下帮助。例如,在后一个例子中,“(?<!bad(\ s {1,99}(\ S {1,99} \ s {1,99}){0,6})good),它可以被重写为“(<?!不好(\ s {1,99}(\ S {1,99} \ S {1,99})?(\ S {1,99} \ S {1,99})?(\ Š{1,99} \ S {1,99})?(\ S {1,99} \ S {1,99})?(\ S {1,99} \ S {1,99})?( \ S {1,99} \ S {1,99})?))好”。 丑,但作品(Java)。 – 2009-12-29 20:06:00

回答

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" 

...和做同样的事情,但它的很多丑陋。

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

+0

我不确定我了解你。如果你的意思是“?<!((。{0,1}){0,1})” - 它不是后视,只是一些chrarcters。如果你的意思是“(?<!(。{0,1}){0,1})” - 没有区别 - 它不是编译。 – 2009-12-29 20:03:30

+0

好的,现在很清楚。我知道我的第一个例子很愚蠢,我只是简单地用卷积量词来说明问题。无论如何,当采集是不必要的时候,我建议您使用非捕获组。 另一件事:根据定义,正则表达式可以处理它。正如我的问题中的链接所述,.NET Regex Engine和他们提到的另一个可以处理无界限的后视。 – 2009-12-30 16:32:22

+0

是的。这就是为什么我把它称为“Java正则表达式的困惑”......但是,在某些时候,有时候将整个字符串标记为\ S标记并对其进行操作有时候会更好。 – PSpeed 2009-12-30 17:31:30