正则expression式在Java中的命名组

这是我的理解, java.regex包不支持命名组( http://www.regular-expressions.info/named.html ),所以任何人都可以指向我的第三方库吗?

我看了jregex,但它的最后一个版本是在2002年,并没有为我工作(承认我只是试了一下)在java5下。

更新2011年8月

正如geofflane在他的回答中提到的那样, Java 7现在支持命名组 。
tchrist在评论中指出,支持是有限的。
详细解释了他的“ Java正则expression式助手 ”

Java 7正则expression式命名组支持于20109月在Oracle的博客中提出 。

在Java 7的正式版本中,支持指定捕获组的构造是:

  • (?<name>X)来定义一个命名组名“
  • \k<name>反向引用一个已命名的组“名称”
  • ${name}引用Matcher的replacestring中的捕获组
  • Matcher.group(String name)通过给定的“命名组”返回捕获的input子序列。

Java之前的其他select是:

  • Google named-regex (参见John Hardy的回答 )
    GáborLipták提到(2012年11月),这个项目可能不是主动的(有几个未解决的bug ),可以考虑使用它的GitHub分支 。
  • jregex (参见Brian Clozel的回答 )

原文答案2009年1月 ,现在有两条链接断了)

你不能引用命名组,除非你编写自己的正则expression式的版本…

这正是Gorbush2在这个线程中所做的 。

Regex2

(有限的实现,正如tchrist再次指出的那样 ,因为它看起来只有ASCII标识符,tchrist的局限性是:

只能够有相同的名称(你不总是有控制!)的一个命名组,并不能使用它们进行in-regexrecursion。

注意:您可以在Perl和PCRE正则expression式中find真正的regexrecursion示例,如Regexp Power , PCRE规范和带平衡括号的匹配string幻灯片中所述)

例:

串:

 "TEST 123" 

正则expression式:

 "(?<login>\\w+) (?<id>\\d+)" 

访问

 matcher.group(1) ==> TEST matcher.group("login") ==> TEST matcher.name(1) ==> login 

更换

 matcher.replaceAll("aaaaa_$1_sssss_$2____") ==> aaaaa_TEST_sssss_123____ matcher.replaceAll("aaaaa_${login}_sssss_${id}____") ==> aaaaa_TEST_sssss_123____ 

(从实施中摘录)

 public final class Pattern implements java.io.Serializable { [...] /** * Parses a group and returns the head node of a set of nodes that process * the group. Sometimes a double return system is used where the tail is * returned in root. */ private Node group0() { boolean capturingGroup = false; Node head = null; Node tail = null; int save = flags; root = null; int ch = next(); if (ch == '?') { ch = skip(); switch (ch) { case '<': // (?<xxx) look behind or group name ch = read(); int start = cursor; [...] // test forGroupName int startChar = ch; while(ASCII.isWord(ch) && ch != '>') ch=read(); if(ch == '>'){ // valid group name int len = cursor-start; int[] newtemp = new int[2*(len) + 2]; //System.arraycopy(temp, start, newtemp, 0, len); StringBuilder name = new StringBuilder(); for(int i = start; i< cursor; i++){ name.append((char)temp[i-1]); } // create Named group head = createGroup(false); ((GroupTail)root).name = name.toString(); capturingGroup = true; tail = root; head.next = expr(tail); break; } 

是的,但它太乱的黑客太阳类。 有一个更简单的方法:

http://code.google.com/p/named-regexp/

named-regexp是标准JDK正则expression式实现的一个精简包装器,具有处理.net风格的命名捕获组的单一目的:(?…)。

它可以与Java 5和6(使用generics)一起使用。

Java 7将处理命名的捕获组,所以这个项目并不意味着持续。

对于那些迟到的人:Java 7添加了命名组。 Matcher.group(String groupName)文档。

你用jregex得到了什么样的问题? 它在java5和java6下运行的很好。

Jregex做得很好(即使最后一个版本是从2002年开始的),除非你想等待javaSE 7 。

对于java7以前的版本, joni ( Oniguruma regexp库的Java端口)支持命名组。 文档很less,但对我们来说运行良好。
二进制文件可以通过Maven获得( http://repository.codehaus.org/org/jruby/joni/joni/ )。

有点古老的问题,但我发现自己也需要这个,以上的build议是不够​​的 – 因此,我自己开发了一个薄包装: https : //github.com/hofmeister/MatchIt