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

时间:2015-04-01 11:37:04

标签: java regex validation

在所有事情之前,

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

版本的格式应为“&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    
}

2 个答案:

答案 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是一个很好的资源,可以让您开始(并且已经超越了)。

您应该同时考虑capturingnot capturing groups以及quantifiersgreedyreluctant

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

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