java - 如何使用正则表达式解析自定义版本号方案?
问题描述
我正在寻找一个正则表达式,它可以匹配一个简单的自定义版本号方案,该方案由无限数量的数字系列组成,在以下约束下由单个句点分隔:
^
通过使用和$
标记在行首和行尾断言位置来匹配单行。由于版本号是单行,因此进行多行匹配是没有意义的。不允许使用字母、空格或特殊字符。
该行不能以句点开头或结尾,并且在初始数字之后的每个后续数字系列必须以单个句点开头。
如前所述,应该假设给定方案可以具有无限数量的类别,因此正则表达式应该能够捕获无限数量的组,每个组代表一个唯一的版本类别。
方案示例
<MajorVersion>.<MinorVersion>.<BuildNumber>
捕获的组
$1 = MajorVersion, $2 = MinorVersion, $3 = BuildNumber
上面可以翻译成一个实际的例子:
Version number: 0.1.2 = [ $1 = 0, $2 = 1, $3 = 2 }
测试用例
Should pass - 010.98
Captured groups = { $1 = 010, $2 = 98 }
Should pass - 0.12.3344.2.1
Captured groups = { $1 = 0, $2 = 12, $3 = 3344, $4 = 2, $5 = 1 }
Should fail - 0 23.42 // Contains white-spaces
Should fail - 1.2..3.4 // Contains consecutive period symbols
Should fail - .2.58.6 // Starts with a period symbol
Should fail - 64#23.4 // Contains special characters
当前解决方案
我正在尝试在 Java 中实现解析解决方案,并且对我当前的解决方案不满意,该解决方案需要我String
两次解析给定的版本号:
- 使用以下正则表达式验证是否
String
是符合上面列出的约束的有效版本号:
^\d+(?:\.\d+)*$
- 一次使用带有以下正则表达式的肯定后向将每个数字系列捕获为单独的版本类别:
(?<=^|\.)\d+
对于那些有兴趣提供 Java 解决方案的人,这里是我用于测试的代码:
public static final Pattern SIMPLE_VERSION_NUMBER_MATCH = Pattern.compile("^\\d{1}(?:\\.\\d)*$");
public static final Pattern SIMPLE_VERSION_NUMBER_GROUPS = Pattern.compile("(?<=^|\\.)\\d+");
@Test
public void testRegExMathCollection() {
String versionNumber = "0.1.2.3";
Assertions.assertTrue(RegExPatterns.SIMPLE_VERSION_NUMBER_MATCH.matcher(versionNumber).find());
assertPatternMatchesGroups(RegExPatterns.SIMPLE_VERSION_NUMBER_GROUPS, versionNumber, "0", "1", "2", "3");
}
@TestOnly
private void assertPatternMatchesGroups(Pattern pattern, String text, String... groups) {
String[] matches = RegExUtils.collectMatches(pattern.matcher(text));
Assertions.assertArrayEquals(groups, matches);
}
public static String[] collectMatches(Matcher matcher) {
List<String> matches = new java.util.ArrayList<>();
while (matcher.find()) {
matches.add(matcher.group());
}
return matches.toArray(new String[0]);
}
问题部分
我对你的问题有两个:
- 使用单个正则表达式解决此问题的最佳方法是什么?
- 如果上述不可行,是否有比我目前使用的更优化的模式?
- 如果您认为正则表达式不是最好的方法,您会推荐什么 Java 实现来解决这个问题?
编辑:请注意,这主要是关于正则表达式的问题,因为主要目标是获得一个能够根据上面提供的约束以及捕获组验证版本号的单个正则表达式。我只要求一个更好的 Java 解决方案作为后备,以防我想要的东西不能用正则表达式来做。
解决方案
使用"1.2.3.4.5".split("\\.")
,查看链接的其他问题。
当您需要在较大的字符串中查找模式,或者当您需要检查字符串是否具有所需的格式,或者当字符串包含您想要忽略的其他字符时,使用正则表达式会更有用。
如果你知道你所有的输入都是格式正确的,那么正则表达式并没有比简单的拆分更有优势。
推荐阅读
- python - 我不明白为什么这些变量有这些值
- jquery - Filter a list of item, Sort and Group By with jQuery
- r - After after updating packages, running library(tidyverse), pipe operator not working
- html - How to make contents on tables align to each other vertically
- python - 所以我在我的学校项目的 Tkinter 代码中不断收到这个名称错误,我不太明白为什么
- java - 是否可以使用 Java 将 PDF 文档转换为 Word?
- python-3.x - 熊猫爆炸了一个列表列,但有额外的列,它指出了列表中的位置
- api - 这是一个什么样的 API?休息还是?
- javascript - 在 jQuery 中构建数组时指定条件
- android - 如何在 Android 上更新 Google Analytics 的清单?