据我了解,java.regex
包不支持命名组 (http://www.regular-expressions.info/named.html),所以任何人都可以将我指向支持的第三方库吗?
我看过 jregex但它的最后一个版本是在 2002 年,它在 java5 下对我不起作用(诚然我只是简单地尝试过)。
最佳答案
(更新:2011 年 8 月)
作为 geofflane his answer 中提及, Java 7 now support named groups .
tchrist在评论中指出支持有限。
他在他的精彩回答“Java Regex Helper”中详细说明了局限性
Java 7 正则表达式命名组支持已在 September 2010 in Oracle's blog 中提供。 .
在 Java 7 的正式版本中,支持命名捕获组的结构是:
(?<name>capturing text)
to define a named group "name"\k<name>
to backreference a named group "name"${name}
to reference to captured group in Matcher's replacement stringMatcher.group(String name)
to return the captured input subsequence by the given "named group".
Java 7 之前的其他替代方案是:
- Google named-regex (见 John Hardy 的 answer )
Gábor Lipták提到(2012 年 11 月)这个项目可能不活跃(使用 several outstanding bugs ),它的 GitHub fork可以考虑。 - jregex (见 Brian Clozel 的 answer )
(原始答案:2009 年 1 月,接下来的两个链接现已断开)
您不能引用命名组,除非您编写自己的正则表达式版本...
这正是Gorbush2 did in this thread .
(有限的实现,正如 tchrist 再次指出的那样,因为它只查找 ASCII 标识符。tchrist 详细说明了限制:
only being able to have one named group per same name (which you don’t always have control over!) and not being able to use them for in-regex recursion.
注意:您可以在 Perl 和 PCRE 正则表达式中找到真正的正则表达式递归示例,如 Regexp Power 中所述。 , PCRE specs和 Matching Strings with Balanced Parentheses幻灯片)
例子:
字符串:
"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;
}
关于java - Java中的正则表达式命名组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/415580/