java.util.Pattern只匹配一个备用组?

时间:2014-08-26 16:54:46

标签: java regex

比如说你有一个java.util.Pattern编译了多个备选方案,每个方案都是一个捕获组:

Pattern pattern = Pattern.compile("(a?bc)|(ab?c)|(abc?)");
Matcher matcher = pattern.matcher("abc");
System.out.println(matcher.matches());
System.out.println(matcher.group(1));
System.out.println(matcher.group(2));
System.out.println(matcher.group(3));

你会看到:

true
abc
null
null

有没有办法让每个捕获组都匹配,或者你总是被限制在一个匹配的组中?

也就是说,因为" abc"匹配上面的每个替代方案,有没有办法将其作为输出:

true
abc
abc
abc

我猜不到,考虑到我对正则表达式的实现的记忆,但我想我会检查。

2 个答案:

答案 0 :(得分:3)

使用轮换时,它只会填充多个组中的一组,但您可以使用前瞻来填充所需的所有3个组:

(?=(a?bc))(?=(ab?c))(?=(abc?))

它会根据您的需要在所有3个组中填充abc

RegEx Demo

Java Code Demo

更新:您还需要使用Matcher#find()才能获得多个匹配项:

Pattern p = Pattern.compile("(?=(a?bc))(?=(ab?c))(?=(abc?))");
Matcher m = p.matcher("abc");
while (m.find()) {
   System.out.printf("%s::<%s> <%s> <%s>%n", m.group(), m.group(1), m.group(2), m.group(3));
}

答案 1 :(得分:0)

我认为,从逻辑上讲,最好将所有备选方案放在一个捕获组中,例如(a?bc|ab?c|abc?),以便将匹配的字符串捕获到第一个组中,当且仅当它匹配一个您的替代方案。

如果你想根据哪些备选方案指定不同的行为,你必须依次检查三个捕获组中的每一个(并将它们与null进行比较),所以你也可以说

if (str.matches("a?bc")) ... 
else if (str.matches("ab?c")) ... 
else if (str.matches("abc?")) ...
else ... // no match

if (str.matches("a?bc")) ... 
if (str.matches("ab?c")) ... 
if (str.matches("abc?")) ...