Java中的正则表达式命名组

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

我看过jregex,但它的最后一次发布是在2002年,它在java5下对我不起作用(诚然,我只简单地尝试过)。

176226 次浏览

(更新: 2011年8月)

正如geofflane他的回答中提到的,Java 7现在支持命名组.
. > tchrist在注释中指出支持是有限的 他详细说明限制在他伟大的回答“Java Regex Helper"

Java 7命名为组支持的正则表达式在 2010年9月在甲骨文的博客中给出。

在Java 7的正式版本中,支持命名捕获组的构造如下:

  • (?<name>capturing text)定义命名组"name"
  • \k<name>反向引用命名组"name"
  • ${name}引用Matcher替换字符串中的捕获组
  • Matcher.group(String name)返回给定“命名组”捕获的输入子序列。

java 7之前的其他替代方案是:


(原来的答案: 2009年1月,下面两个链接现在断开)

您不能引用命名组,除非您编写了自己的Regex版本…

这正是Gorbush2在这篇文章中提到了

Regex2

(有限的实现,正如tchrist再次指出的那样,因为它只查找ASCII标识符。Tchrist详述了限制如下:

每个相同的名称只能有一个命名组(您并不总是能够控制!),并且不能将它们用于正则表达式内递归。

注意:你可以在Perl和PCRE正则表达式中找到真正的正则递归示例,如Regexp权力PCRE规格用平衡括号匹配字符串幻灯片所述)

例子:

字符串:

"TEST 123"

正则表达式:

"(?<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正则表达式 实现,用单 处理命名捕获的目的 .net样式中的组: (?…)。< / p >

它可以与Java 5和6一起使用 (使用泛型).

Java 7将处理命名捕获 群体,所以这个项目不是指 最后。< / p >
你使用jregex会遇到什么样的问题? 它在java5和java6下工作得很好

Jregex很好地完成了这项工作(即使上一个版本是2002年的),除非你需要等待javaSE 7

对于晚到的人:Java 7添加了命名组。匹配器。group(String groupName)文档。

对于那些运行java7之前的对象,命名组由乔妮 (Oniguruma regexp库的Java端口)支持。文档很少,但它对我们来说工作得很好 二进制文件可通过Maven (http://repository.codehaus.org/org/jruby/joni/joni/)获得

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