我有一个正则表达式,用于查找字符串内<>之间的逗号分隔单词列表的匹配项,如示例中的"Hello <a1> sqjsjqk <b1,b2> dsjkfjkdsf <c1,c2,c3> ffsd"
我想使用捕获组来保留大括号之间的每个单词:
这是我的表达式:< (w+) (?: ,(w+) )* >
(添加空格是为了可读性,但不是模式的一部分)
括号用于创建捕获组,(?: )
用于创建非捕获组,因为我不想保留昏迷。
这是我的测试代码:
@Test
public void test() {
String patternString = "<(\w+)(?:,(\w+))*>";
Pattern pattern = Pattern.compile(patternString);
Matcher matcher = pattern.matcher("Hello <a1> sqjsjqk <b1,b2> dsjkfjkdsf <c1,c2,c3> ffsd");
while(matcher.find()) {
System.out.println("== Match ==");
MatchResult matchResult = matcher.toMatchResult();
for(int i = 0; i < matchResult.groupCount(); i++) {
System.out.println(" " + matchResult.group(i + 1));
}
}
}
这是生成的输出:
== Match ==
a1
null
== Match ==
b1
b2
== Match ==
c1
c3
这就是我想要的:
== Match ==
a1
== Match ==
b1
b2
== Match ==
c1
c2
c3
由此我了解到,我的表达式中的组数与捕获组的数量正好一样多,但这不是我想要的,因为我需要所有被识别为w+
的子字符串
有没有机会用一个正则表达式得到我想要的东西,或者我应该用split(",")
、trim()
等来完成这项工作......
据我所知,.NET 拥有唯一的正则表达式引擎,可以为单个捕获组返回多个捕获。所以你所要求的在Java中是不可能的(至少不是你要求的方式)。
但是,在您的情况下,可以在一定程度上解决此问题。如果你能确定永远不会有不匹配的收盘>
,你可以做出你想要捕捉完整匹配的东西,并通过前瞻要求正确的位置:
"\w+(?=(?:,\w+)*>)"
这永远无法匹配<...>
之外的"单词",因为它们无法通过开场<
来匹配结束>
。当然,这使得很难区分来自不同<...>
集的元素。
或者(我想这更好,因为它更安全,更具可读性),选择两步算法。第一场比赛
"<([\w,]*)>"
然后在,
split
每个结果的第一次捕获。