JDK版本1.8
命名捕获组的形式
(?<name>X) X, as a named-capturing group
命名捕获组应用
@Test
public void namedGroup() {
Pattern pattern = Pattern.compile("(?<text>.*)");
Matcher matcher = pattern.matcher("abc");
if(matcher.matches()){
//输出abc
System.out.println(matcher.group("text"));
}
}
}
引申
如何在不硬编码groupName的情况下去遍历一个正则中的所有命名组?
通过查看Pattern中的源码可以看到
public final class Pattern
implements java.io.Serializable
{
//...
/**
* Map the "name" of the "named capturing group" to its group id
* node.
*/
transient volatile Map<String, Integer> namedGroups;
//...
Map<String, Integer> namedGroups() {
if (namedGroups == null)
namedGroups = new HashMap<>(2);
return namedGroups;
}
//...
}
可惜不能直接访问namedGroups()来获取,不过可以利用反射来获取该属性。
遍历命名捕获组正则中的name
@Test
public void namedGroups() {
Pattern pattern = Pattern.compile("(?<text>.*)");
Matcher matcher = pattern.matcher("abc");
Map<String, Integer> namedGroups = RegexHelper.namedGroups(pattern);
if (matcher.matches()) {
for (Entry<String, Integer> entry : namedGroups.entrySet()) {
System.out
.println("groupName:" + entry.getKey() + ",value:" + matcher.group(entry.getKey()));
}
}
}
public static class RegexHelper {
private static final Method namedGroups;
static {
Method namedGroupsMethod = ReflectionUtils.findMethod(Pattern.class, "namedGroups");
ReflectionUtils.makeAccessible(namedGroupsMethod);
namedGroups = namedGroupsMethod;
}
public static Map<String, Integer> namedGroups(Pattern pattern) {
Objects.requireNonNull(pattern, "pattern");
try {
return (Map<String, Integer>) namedGroups.invoke(pattern);
} catch (IllegalAccessException | InvocationTargetException e) {
throw new RuntimeException(e);
}
}
}