在所有事情之前,
版本的格式应为“&lt; major&gt;。&lt; minor&gt;。&lt; beta&gt;”其中任一个具有范围<0-999&gt;
我想要的行为如下
0 - 0.0.0
1 - 1.0.0
000.0.0 - 0.0.0
..9 - 0.0.9
00007 - 7.0.0
090876 - validate as false
9.00098000.00 - validate as false
9.0900000.00 - 9.09.0
-13.0.4 - validate as false
1a.0.4b - validate as false
我的解决方案如下
if (StringUtils.isBlank(version)) {
//set error
} else {
if (!this.version.trim().matches("\\d+") && !(this.version.trim().matches("^-+"))
&& !(this.version.trim().matches("^+"))) {
String[] versionsplit = this.version.split("\\.");
// in the format <major>.<minor>.<beta> for major version, only
// leading zeroes should be removed
versionsplit[0] = versionsplit[0].trim().replaceFirst("^0+(?!$)", "");
if (versionsplit[0].length() == 0) {
// if major version is left blank add 0
versionsplit[0] = "0";
}
for (int i = 1; i < versionsplit.length; i++) {
// for minor and beta versions, trailing zeroes should be
// removed
versionsplit[i] = versionsplit[i].trim().replaceAll("0*$", "");
if (versionsplit[i].length() == 0) {
versionsplit[i] = "0";
}
}
this.version = StringUtils.join(versionsplit, ".");
if (versionsplit.length < 3) {
// to comply with the standard format <major>.<minor>.<beta>
for (int i = versionsplit.length; i < 3; i++) {
version += ".0";
}
}
} else {
//set error
}
if(< no error check > && !(version.matches("\\d(\\d(\\d)?)?(\\.\\d(\\d(\\d)?)?(\\.\\d(\\d(\\d)?)?)?)?"))) {
// set error
}
}
告诉我这是不是最复杂的解决方案,我很乐意让它成为现实。我只是希望代码对下一个人来说是可读的。
请询问要求是否不清楚。如果我没有立即回复,请不要感到沮丧,因为我不总是在线
提前致谢。
修改
我理解最后的格式检查器在下面的方式更准确。
if(< no error check > && !(version.matches("(?:[0-9]{1,3}\\.){2}[0-9]{1,3}$"))) {
// set error
}
答案 0 :(得分:0)
不确定它是否更好),但这就是我所拥有的:
public static Pattern pattern = Pattern.compile("([\\d]*)[\\.]?([\\d]*)[\\.]?([\\d]*)");
public static boolean check(String input) {
Matcher matcher = pattern.matcher(input);
if(!matcher.matches()){
// NOT MATCH
return false;
}
String major = handleMajor(matcher.group(1));
String minor = handleMinor(matcher.group(2));
String rev = handleMinor(matcher.group(3));
if (major.length() > 3 || minor.length() > 3 || rev.length() > 3 ){
// NOT MATCH: over the range 0-999
return false;
}
// MATCH !!!
System.out.println(major + "." + minor + "." + rev);
return true;
}
private static String handleMajor(String in){
if (in.matches("(0*)")) { // replace "" or "00000" with "0"
return "0";
} else { // remove leading zeros
return in.replaceFirst("(0+)", "");
}
}
private static String handleMinor(String in){
if (in.matches("(0*)")) { // replace "" or "00000" with "000"
return "000";
} else { // remove trailing zeros
String res = in + "00";
while(res.endsWith("0") && res.length() > 3) {
res = res.substring(0, res.length() - 1);
}
return res;
}
}
答案 1 :(得分:0)
基本上,您只需要更好地理解正则表达式以及它们如何在Java中工作。
这是我的代码示例以及相应的输出,解释如下:
List<String> versions = Arrays.asList("0", "1", "000.0.0", "100.2.3","1.2.3", "..9", "00007", "090876", "9.00098000.00", "9.0900000.00", "-13.0.4", "1a.0.4b", "1.2");
Pattern pattern = Pattern.compile("^0*([1-9][0-9]{0,2})?(?:\\.([0-9]{0,3}?)0*(?:\\.([0-9]{0,3}?)0*)?)?$");
for (String v : versions) {
Matcher matcher = pattern.matcher(v);
Boolean matches = matcher.matches();
Integer groups = matcher.groupCount();
System.out.print(v + " evaluates to " + matches);
// groups is always 3, because the empty string also matches
if (matches) {
String major = matcher.group(1);
if (major == null || major.isEmpty()) {
major = "0";
}
String minor = matcher.group(2);
if (minor == null || minor.isEmpty()) {
minor = "0";
}
String beta = matcher.group(3);
if (beta == null || beta.isEmpty()) {
beta = "0";
}
System.out.println(" ---> " + major + "." + minor + "." + beta);
} else {
System.out.println();
// error handling
}
}
这导致以下输出:
0 evaluates to true ---> 0.0.0
1 evaluates to true ---> 1.0.0
000.0.0 evaluates to true ---> 0.0.0
100.2.3 evaluates to true ---> 100.2.3
1.2.3 evaluates to true ---> 1.2.3
..9 evaluates to true ---> 0.0.9
00007 evaluates to true ---> 7.0.0
090876 evaluates to false
9.00098000.00 evaluates to false
9.0900000.00 evaluates to true ---> 9.09.0
-13.0.4 evaluates to false
1a.0.4b evaluates to false
1.2 evaluates to true ---> 1.2.0
所有内容都围绕模式及其编译的正则表达式展开。使用Java中的正则表达式https://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html?is-external=true是一个很好的资源,可以让您开始(并且已经超越了)。
您应该同时考虑capturing
和not capturing groups
以及quantifiers
,greedy
和reluctant
。
我在上面提供的正则表达式([1-9][0-9]{0,2})?
是主要版本的捕获组。它必须以0以外的数字开头,并且最多可包含2个数字字符(此时包含0)。由于正则表达式中的前导0*
,所有前导空值都被丢弃 - 观察它是如何不在任何捕获组内的。最后的贪心量词?
表示该组是可选的。下一组也是可选的,并且它还是非捕获组,即在匹配完成后将无法访问它。在其中我丢弃一些零并捕获另外两组,其中一组是可选的,使用相同的原则。
编辑:根据作者的建议,修改了接受x.y等版本字符串的答案。