据我了解,该java.regex
软件包不支持命名组(http://www.regular-expressions.info/named.html),所以有人可以将我指向具有此名称的第三方库吗?
我看过jregex,但是它的最新版本是2002年,它在java5下对我不起作用(诚然,我只是简短地尝试过)。
据我了解,该java.regex
软件包不支持命名组(http://www.regular-expressions.info/named.html),所以有人可以将我指向具有此名称的第三方库吗?
我看过jregex,但是它的最新版本是2002年,它在java5下对我不起作用(诚然,我只是简短地尝试过)。
Answers:
(更新:2011年8月)
正如geofflane在回答中提到的那样,Java 7现在支持命名组。
tchrist在评论中指出支持有限。
他在出色的答案“ Java Regex Helper ”中详细说明了局限性
早在2010年9月,Oracle博客就提出了Java 7正则表达式(称为组支持)。
在Java 7的正式版本中,支持命名捕获组的构造为:
(?<name>capturing text)
定义一个命名组“名称”\k<name>
向后引用命名组“名称”${name}
引用匹配器替换字符串中的捕获组Matcher.group(String name)
以给定的“命名组”返回捕获的输入子序列。
Java 7之前的其他替代方法是:
(原始答案:2009年1月,以下两个链接现在断开了)
您不能引用命名组,除非您编写自己的Regex版本。
这正是Gorbush2在此线程中所做的。
(受限的实现,正如tchrist再次指出的那样,因为它仅查找ASCII标识符。tchrist将限制详细说明为:
每个名称只能具有一个命名组(您并不总是可以控制!),并且不能将它们用于正则表达式递归。
注意:您可以在Perl和PCRE正则表达式中找到真正的正则表达式递归示例,如Regexp Power,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;
}
对于那些迟到的人:Java 7添加了命名组。Matcher.group(String groupName)文档。
是的,但是它凌乱地侵入了阳光课。有一个更简单的方法:
http://code.google.com/p/named-regexp/
named-regexp是标准JDK正则表达式实现的精简包装,其单一目的是处理.net样式的命名捕获组:(?...)。
它可以与Java 5和6(使用泛型)一起使用。
Java 7将处理命名的捕获组,因此该项目不打算持续下去。
您使用jregex会遇到什么问题?在java5和java6下对我来说效果很好。
Jregex做得很好(即使最新版本是2002年),除非您想等待javaSE 7。
有点老的问题了,但我发现自己也需要这个,并且上面的建议不够用,因此,我自己开发了一个薄包装器:https : //github.com/hofmeister/MatchIt