通过 Java 正则表达式提取 semver 版本字符串的片段

Extracting segments of a semver version string via Java regex

Java 8 在这里。我正在尝试解析 semver(或者至少是我的 semver 风格)字符串并提取其主要部分:

这是我的代码:

String version = "1.0.1-RC";
Pattern versionPattern = Pattern.compile("^[1-9]\d*\.\d+\.\d+(?:-[a-zA-Z0-9]+)?$");
Matcher matcher = versionPattern.matcher(version);

if (matcher.matches()) {

    System.out.println("\n\n\matching version is: " + matcher.group(0));
    System.out.println("\nmajor #: " + matcher.group(1));
    System.out.println("\nminor #: " + matcher.group(2));
    System.out.println("\npatch #: " + matcher.group(3));
    System.out.println("\nqualifier: " + matcher.group(4) + "\n\n\n");

}

运行时,我在控制台上得到以下输出:

matching version is: 1.0.1-RC
2019-10-18 14:32:05,952 [main] 84b37cef-70f9-4ab8-bafb-005821699766 ERROR c.s.f.s.listeners.StartupListener - java.lang.IndexOutOfBoundsException: No group 1

我需要对我的正则表达式做些什么 and/our 使用匹配器 API 以便我可以提取:

有什么想法吗?

注意:

  • 您不应在字符串文字中转义 m\m 不是有效的字符串转义序列,代码将无法编译
  • Matcher#matches()需要全字符串匹配,不需要添加^$锚点
  • 为了能够引用Matcher#group(n),您需要首先在模式中定义组。用一对未转义的括号将您需要的部分包裹起来。

使用

String version = "1.0.1-RC";
Pattern versionPattern = Pattern.compile("([1-9]\d*)\.(\d+)\.(\d+)(?:-([a-zA-Z0-9]+))?");
Matcher matcher = versionPattern.matcher(version);

if (matcher.matches()) {
    System.out.println("matching version is: " + matcher.group(0));
    System.out.println("major #: " + matcher.group(1));
    System.out.println("minor #: " + matcher.group(2));
    System.out.println("patch #: " + matcher.group(3));
    System.out.println("qualifier: " + matcher.group(4) + "\n\n\n");
}

Java demo,输出:

matching version is: 1.0.1-RC
major #: 1
minor #: 0
patch #: 1
qualifier: RC

我四处查看 semver 规范 website 并在那里找到了一个有效的正则表达式,我对其进行了一些修复以使用 java 正则表达式命名组,如果有人的话,这里是正则表达式需要它

final static String version_regex = "^(?<major>0|[1-9]\d*)\.(?<minor>0|[1-9]\d*)\.(?<patch>0|[1-9]\d*)(?:-(?<prerelease>(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+(?<buildmetadata>[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$";

// After matching to grab the groups
String mayor = matcher.group("major");
String minor = matcher.group("minor");
String patch = matcher.group("patch");
String prerelease = matcher.group("prerelease");
String buildmetadata = matcher.group("buildmetadata");