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

Java中Look-behind组明显最大长度的存在性,java,regex,Java,Regex,在此Java代码中: public class Main { public static void main(String[] args) { "".matches("(?<!((.{0,1}){0,1}))"); } } 公共类主{ 公共静态void main(字符串[]args){ “”匹配项(“(?”); } } 编译器(我使用的是JVM 1.6.0_17-b04)会喊出“异常……查找组没有明显的最大长度”。我看到: Java更进一步,允许有限重复。您仍然不能使用星号

在此Java代码中:

public class Main {
  public static void main(String[] args) {
    "".matches("(?<!((.{0,1}){0,1}))");
  }
}
公共类主{
公共静态void main(字符串[]args){
“”匹配项(“(?”);
}
}
编译器(我使用的是JVM 1.6.0_17-b04)会喊出“异常……查找组没有明显的最大长度”。我看到:

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

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

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

(?<!bad(\s{1,99}(\S{1,99}\s{1,99}){0,6}))good (? (好词,后面没有坏词,在7个词的范围内)


如何修复它?

如果您从负面外观中删除了捕获组,那么它似乎可以编译。我甚至不确定负面外观中的意图是什么,或者捕获组应该做什么。这是故意的吗

编辑以澄清:

你写了正则表达式:

"(?<!((.{0,1}){0,1}))"
例如,上面的部分可以正常工作。如果您确实需要负look back中的括号,那么您应该使用非捕获组,如“(?: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"

(?我不确定我是否理解你的意思。如果你的意思是”?好的,现在很清楚了。我知道我的第一个例子很傻;我只是简单地用卷曲量词来演示组上卷曲量词的问题。无论如何,我接受了你的建议,当不需要捕获时,使用非捕获组。另一件事:根据定义,正则表达式可以处理它。正如我的问题中的链接所述在.NET上,Regex引擎和他们提到的另一个引擎可以处理无边界look-behinds.True。这就是为什么我称之为“Java Regex的混淆”…但是,在某些情况下,有时最好将整个字符串标记为\s标记并对其进行操作。在某些情况下,可以使用walk-around。例如,在后一个示例中,(?)?
"(?<!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"