代码之家  ›  专栏  ›  技术社区  ›  Yaakov Shoham

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

  •  2
  • Yaakov Shoham  · 技术社区  · 15 年前

    在此Java代码中:

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

    here 即:

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

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

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

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

    我怎样才能修好它?

    1 回复  |  直到 15 年前
        1
  •  3
  •   PSpeed    15 年前

    如果您将捕获组从负面外观中删除,那么它似乎可以编译。我甚至不知道他们的意图是什么,或者在消极的背后,捕获小组应该做什么。这是故意的吗?

    编辑以澄清:

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

    这个 "(?<!" part表示反向查找,如您希望查找匹配项 先发制人。然而,这里挤满了俘虏组织。。。ie:所有这些都是裸体的 ()

    去掉所有的括号,你就不会再得到错误了。。。更不用说它们是不必要的:

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

    例如,上面的部分可以正常工作。如果您确实需要在负数look back中使用括号,那么应该使用非捕获组,如“(?:mypattern)”。在这个简单的例子中,它们实际上并没有为您做任何事情,而且双精度{0,1}有点多余。

    因此,我试图让您更复杂的示例工作,即使切换到非捕获组也无法消除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"
    

    …做同样的事,但要丑陋得多。

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