非捕获组内的捕获组

4

我目前遇到了解析类似版本的字符串的困难。

我的正则表达式是 v(\\d+)_(\\d+)(?:_(\\d+))?,它应该匹配以下格式的字符串:vVersion_InterimVersion_PatchVersion。我的目标是,最后一个匹配组(_PatchVersion)是可选的。

我的问题在于可选部分。一个字符串 v1_00 将给我一个 matcher.groupCount 为3。我本来期望的是2个组。所以我猜我的正则表达式可能有误,或者我不理解 matcher.groupCount

public static void main(final String[] args) {

    final String versionString = "v1_00";

    final String regex = "v(\\d+)_(\\d+)(?:_(\\d+))?";

    final Matcher matcher = Pattern.compile(regex).matcher(apiVersionString);
    if (matcher.matches()) {

      final int version = Integer.parseInt(matcher.group(1));
      final int interimVersion = Integer.parseInt(matcher.group(2));
      int patchVersion = 0;
      if (matcher.groupCount() == 3) {
        patchVersion = Integer.parseInt(matcher.group(3));
      }
      // ...

    }
}

非捕获组仍然是一个组,这就是为什么它返回它所做的事情。groupCount实际上是Pattern的状态,而不是Matcher的状态,并且主要用于使用类似于索引集合的匹配器的东西中。 - M. Prokhorov
1个回答

6

正则表达式中有多少个捕获组就会有多少个匹配组。如果你的模式中有3组未转义的括号,那么就会有 matcher.group(1)matcher.group(2)matcher.group(3)

如果第三个捕获组没有匹配成功,它的值将为 null。请检查第三个捕获组的值是否为 null

if (matcher.group(3) != null) {
    patchVersion = Integer.parseInt(matcher.group(3));
}

请看Java在线演示
final String versionString = "v1_00";
final String regex = "v(\\d+)_(\\d+)(?:_(\\d+))?";
final Matcher matcher = Pattern.compile(regex).matcher(versionString);
if (matcher.matches()) {
    final int version = Integer.parseInt(matcher.group(1));
    final int interimVersion = Integer.parseInt(matcher.group(2));
    int patchVersion = 0;
    if (matcher.group(3) != null) {
        patchVersion = Integer.parseInt(matcher.group(3));
    }
    System.out.println(version + " > " + interimVersion  + " > " + patchVersion);
}

Results: 1 > 0 > 0.


1
对于一行代码,可以使用Optional.ofNullable(matcher.group(3)).map(Integer::parseInt).orElse(0) - M. Prokhorov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接