【问题标题】:Why does the look-behind expression in this regex not have an "obvious maximum length"?为什么这个正则表达式中的后视表达式没有“明显的最大长度”?
【发布时间】:2011-10-06 19:23:53
【问题描述】:

给定一个包含一些方括号和其他字符的字符串,我想找到所有右方括号前面有一个左方括号和一些字母。 例如,如果字符串是

] [abc] [123] abc]

我只想找到第二个右括号。

以下正则表达式

(?

会发现我是第二个右括号,也是最后一个:

] [abc] [123] abc]

由于我只想找到第一个,因此我对正则表达式进行了明显的更改...

(?\[[a-z]+)\]

...我得到“后视组在索引 11 附近没有明显的最大长度。”

\[ 只是一个字符,所以看起来明显的最大长度应该是 1 + 无论第一个表达式中后视组的明显最大长度是什么。什么给了?


预计到达时间:它并不特定于左括号。

(?

给了我同样的错误。 (好吧,在索引 12 处。)

【问题讨论】:

    标签: java regex


    【解决方案1】:

    \[ 只是一个字符,所以看起来明显的最大长度应该是 1 + 无论第一个表达式中后视组的明显最大长度是什么。什么给了?

    这就是重点,“无论第一个表达式中后视组的明显最大长度是多少”,不是显而易见的。拳头规则是您不能在后视中使用+ 或*。这不仅适用于 Java 的正则表达式引擎,而且适用于更多 PCRE 风格的引擎(甚至 Perl 的 (v5.10) 引擎!)。

    不过,您可以通过前瞻来做到这一点:

    Pattern p = Pattern.compile("(?=(\\[[a-z]+]))");
    Matcher m = p.matcher("] [abc] [123] abc]");
    while(m.find()) {
      System.out.println("Found a ']' before index: " + m.end(1));
    }
    

    (即前瞻 (!) 中的捕获组,可用于获取组的 end(...))

    将打印:

    在 index: 7 之前找到一个 ']'

    编辑

    如果您有兴趣替换此类],您可以执行以下操作:

    String s = "] [abc] [123] abc] [foo] bar]";
    System.out.println(s);
    System.out.println(s.replaceAll("(\\[[a-z]+)]", "$1_"));
    

    将打印:

    ] [abc] [123] abc] [foo] bar]
    ] [abc_ [123] abc] [foo_ bar]

    【讨论】:

    • @David,可能是 regex-API 中反复出现的错误(请参阅:stackoverflow.com/questions/1536915/… 和 bugs.sun.com/view_bug.do?bug_id=6695369)
    • 那么我是否正确地认为没有一个正则表达式可以让我只得到括号 - 例如,我可以在 String.replace() 中使用的东西?
    • 不,你错了:)。请参阅我的编辑。 (注意replace(...) 不使用正则表达式,它的replaceAll(...) 或replaceFirst(...))
    • 对不起,我是想说replaceAll()。
    【解决方案2】:
     "^[^\[]*\[[^\]]*?(\])"
    

    组(1)是你想要的吗?

    【讨论】:

      猜你喜欢
      • 2010-12-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-19
      相关资源
      最近更新 更多