代码之家  ›  专栏  ›  技术社区  ›  polygenelubricants

回溯中的回溯

  •  10
  • polygenelubricants  · 技术社区  · 15 年前

    你能在回溯中使用回溯吗?

    假设我想 split 在我身后的任何地方,一个角色都会重复两次。

        String REGEX1 = "(?<=(.)\\1)"; // DOESN'T WORK!
        String REGEX2 = "(?<=(?=(.)\\1)..)"; // WORKS!
    
        System.out.println(java.util.Arrays.toString(
            "Bazooka killed the poor aardvark (yummy!)"
            .split(REGEX2)
        )); // prints "[Bazoo, ka kill, ed the poo, r aa, rdvark (yumm, y!)]"
    

    使用 REGEX2 (backreference位于lookbehind中嵌套的lookahead中)可以工作,但是 REGEX1 在运行时出现此错误:

    Look-behind group does not have an obvious maximum length near index 8
    (?<=(.)\1)
            ^
    

    这个 某种程度上 我想这是有道理的,因为一般情况下,反向引用可以捕获任意长度的字符串(不过,如果regex编译器更聪明一点,它可以确定 \1 (.) 在这种情况下,因此具有有限的长度)。

    那么在lookback中有没有方法使用backreference呢?

    如果没有,你能一直使用这个嵌套的lookahead来解决它吗?还有其他常用的技巧吗?

    1 回复  |  直到 15 年前
        1
  •  5
  •   Tim Pietzcker    15 年前

    看来您的怀疑是正确的,反向引用一般不能在Java查找表中使用。你提出的解决方法使lookbehind的有限长度变得明确,在我看来非常聪明。

    我很想知道python对这个regex做了什么。Python只支持固定长度的查找,而不是像Java一样的有限长度,但是这个正则表达式是固定长度的。我不能用 re.split() 直接因为python的 拆分() 从不在空火柴上裂开,但我想我在 re.sub() :

    >>> r=re.compile("(?<=(.)\\1)")
    >>> a=re.sub(r,"|", "Bazooka killed the poor aardvark (yummy!)")
    >>> a
    'Bazo|oka kil|led the po|or a|ardvark (yum|my!)'
    

    后面的火柴 之间 两个重复的字符!

    推荐文章