java regex group,在java regex中获取组名

这篇博客讨论了在Java中如何从正则表达式中获取命名捕获组的问题。由于Java的regex API没有提供直接获取组名的方法,作者提出了一种通过匹配模式来找出可能的命名组,并在实际匹配字符串时验证这些组的有效性。博客提供了一个实现,包括获取命名组候选、编译模式、匹配输入和打印匹配结果的步骤。然而,这种方法不适用于包含注释模式的正则表达式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

I'm trying to receive both a pattern & a string and return a map of group name -> matched result.

Example:

(?.*)

I would like to return for a map containing "user" as a key and whatever it matches as its value.

the problem is that I can't seem to get the group name from the Java regex api. I can only get the matched values by name or by index. I don't have the list of group names and neither Pattern nor Matcher seem to expose this information.

I have checked its source and it seems as if the information is there - it's just not exposed to the user.

I tried both Java's java.util.regex and jregex. (and don't really care if someone suggested any other library that is good, supported & high in terms performance that supports this feature).

解决方案

There is no API in Java to obtain the names of the named capturing groups. I think this is a missing feature.

The easy way out is to pick out candidate named capturing groups from the pattern, then try to access the named group from the match. In other words, you don't know the exact names of the named capturing groups, until you plug in a string that matches the whole pattern.

The Pattern to capture the names of the named capturing group is \(\? (derived based on Pattern class documentation).

(The hard way is to implement a parser for regex and get the names of the capturing groups).

A sample implementation:

import java.util.Scanner;

import java.util.Set;

import java.util.TreeSet;

import java.util.Iterator;

import java.util.regex.Pattern;

import java.util.regex.Matcher;

import java.util.regex.MatchResult;

class RegexTester {

public static void main(String args[]) {

Scanner scanner = new Scanner(System.in);

String regex = scanner.nextLine();

StringBuilder input = new StringBuilder();

while (scanner.hasNextLine()) {

input.append(scanner.nextLine()).append('\n');

}

Set namedGroups = getNamedGroupCandidates(regex);

Pattern p = Pattern.compile(regex);

Matcher m = p.matcher(input);

int groupCount = m.groupCount();

int matchCount = 0;

if (m.find()) {

// Remove invalid groups

Iterator i = namedGroups.iterator();

while (i.hasNext()) {

try {

m.group(i.next());

} catch (IllegalArgumentException e) {

i.remove();

}

}

matchCount += 1;

System.out.println("Match " + matchCount + ":");

System.out.println("=" + m.group() + "=");

System.out.println();

printMatches(m, namedGroups);

while (m.find()) {

matchCount += 1;

System.out.println("Match " + matchCount + ":");

System.out.println("=" + m.group() + "=");

System.out.println();

printMatches(m, namedGroups);

}

}

}

private static void printMatches(Matcher matcher, Set namedGroups) {

for (String name: namedGroups) {

String matchedString = matcher.group(name);

if (matchedString != null) {

System.out.println(name + "=" + matchedString + "=");

} else {

System.out.println(name + "_");

}

}

System.out.println();

for (int i = 1; i < matcher.groupCount(); i++) {

String matchedString = matcher.group(i);

if (matchedString != null) {

System.out.println(i + "=" + matchedString + "=");

} else {

System.out.println(i + "_");

}

}

System.out.println();

}

private static Set getNamedGroupCandidates(String regex) {

Set namedGroups = new TreeSet();

Matcher m = Pattern.compile("\\(\\?").matcher(regex);

while (m.find()) {

namedGroups.add(m.group(1));

}

return namedGroups;

}

}

}

There is a caveat to this implementation, though. It currently doesn't work with regex in Pattern.COMMENTS mode.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值