java - 格式为 <0-999>.<0-999>.<0-999> 的版本的简化正则表达式解决方案

标签 java regex validation

首先,

  • 我已经解决了其他几个与正则表达式相关的问题,也成功地提出了一个解决方案,但看起来可能有一个更简单的解决方案
  • 我是正则表达式的初学者
  • 我正在使用 java 来执行此服务器端

版本的格式应为“..”,其中任何一个的范围为<0-999>

我想要的行为如下

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    
}

最佳答案

基本上,您所需要的只是更好地理解正则表达式及其在 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

一切都围绕着模式和它所编译的正则表达式。 https://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html?is-external=true是一个很棒的资源,可以帮助您开始(甚至超越开始)使用 Java 中的正则表达式。

您应该研究捕获不捕获组量词,无论是贪婪还是不情愿

在我上面提供的正则表达式中,([1-9][0-9]{0,2})? 是主要版本的捕获组。它必须以 0 以外的数字开头,并且后面最多可以有 2 个数字字符(这次包括 0)。由于正则表达式中的前导 0* ,所有前导空值都被丢弃 - 观察它如何不在任何捕获组内。末尾的贪婪量词 ? 表示该组是可选的。下一组也是可选的,并且它还是一个非捕获组,即比赛结束后将无法访问它。在其中,我丢弃了一些零并捕获了另外两组,其中一组是可选的,使用的原理完全相同。

编辑:修改答案以接受作者建议的 x.y 等版本字符串。

关于java - 格式为 <0-999>.<0-999>.<0-999> 的版本的简化正则表达式解决方案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29389740/

相关文章:

java - 尝试创建 CGLIB Spring 代理时出现 InaccessibleObjectException

java - 如何动态更新 RX Observable?

java - Map<String, Collection<Object>> 是否可以在 Spring 中声明

javascript - 在 javascript 中更改边框颜色的问题

java - 您如何验证在 Android 2.1 中输入的 EditTextPreference 的格式和值?

java - 使用 hashmap 时什么时候需要重写 hashcode() 和 equals()

java - 如何控制 Java 正则表达式中的迭代步骤?

java - 匹配后获取后续行,直到行与其他模式匹配

python - 在 python 中创建正则表达式时忽略特殊字符

javascript - 有没有办法为 HTML5 输入的模式属性应用正则表达式修饰符?