比较版本号字符串(主要、次要、修订版、测试版)

2022-09-03 17:24:23

我有一个与设备固件通信的应用程序。由于固件有更改,因此使用格式进行版本控制。举几个例子,当前版本是后面跟着,偶尔跟着,然后是。不幸的是,固件的版本控制格式不在我的控制之下,因此我无法更改它。{major}.{minor}.{revision}[beta[{beta}]]0.4.7beta0.4.7beta20.4.70.4.8beta

我需要一种相互比较固件的方法。基本上,我需要一个函数

boolean isFirmwareNewer(String testFW, String baseFW);

到目前为止,我所做的是将此格式转换为简单的.所以会变成(每个级别2位数字)。问题是,int0.4.7beta200040702

  1. 我的代码难以阅读(>40行和3种方法)
  2. 我敢肯定,有一个优雅的解决方案(也许使用正则表达式?
  3. 我想要一个根据定义更新的通配符0.0.0
  4. 这将处理不正确的测试版(不比 )这很容易解释(,但它也不是很优雅。0.4.7beta20.4.7if (testFW.contains("beta")) testFWValue -= 100;

你们通常如何做到这一点(或者你会怎么做)?

如果你愿意,我可以附加我目前正在使用的代码,但正如我所说,它是>40行代码,并不真正可读(这就是我正在寻找更好的方法来做到这一点的原因)。


答案 1

这里有一个建议:

static int[] getVersionNumbers(String ver) {
    Matcher m = Pattern.compile("(\\d+)\\.(\\d+)\\.(\\d+)(beta(\\d*))?")
                       .matcher(ver);
    if (!m.matches())
        throw new IllegalArgumentException("Malformed FW version");

    return new int[] { Integer.parseInt(m.group(1)),  // major
            Integer.parseInt(m.group(2)),             // minor
            Integer.parseInt(m.group(3)),             // rev.
            m.group(4) == null ? Integer.MAX_VALUE    // no beta suffix
                    : m.group(5).isEmpty() ? 1        // "beta"
                    : Integer.parseInt(m.group(5))    // "beta3"
    };
}

static boolean isFirmwareNewer(String testFW, String baseFW) {

    int[] testVer = getVersionNumbers(testFW);
    int[] baseVer = getVersionNumbers(baseFW);

    for (int i = 0; i < testVer.length; i++)
        if (testVer[i] != baseVer[i])
            return testVer[i] > baseVer[i];

    return true;
}

它使用了一个小技巧,并按如下方式翻译beta部分:

  • ""(无测试版后缀) → 测试版 MAX_INT
  • "beta"→ Beta 1(因为它早于“beta2”)
  • "betaX"→ 测试版 X

请注意,如果两个版本相同,则返回。true


答案 2

我将实现一个类似的类:

class Version implements Comparable<Version> {
    int major;
    int minor;
    int rev;
    int beta = Integer.MAX_VALUE;


    public int compareTo(Version o) {
        if (this.major != o.major) {
            return Integer.compare(this.major, o.major);
        }
        if (this.minor != o.minor) {
            return Integer.compare(this.minor, o.minor);
        }
        if (this.rev != o.rev) {
            return Integer.compare(this.rev, o.rev);
        }
        if (this.beta != o.beta) {
            return Integer.compare(this.beta, o.beta);
        }
        return 0;
    }


    public static Version parse(String version) {
        // TODO: implement parsing here
        // 1.1.1      - beta = MAX_VALUE
        // 1.1.1beta  - beta = 1
        // 1.1.1beta2 - beta = 2
        return new Version();
    }


    @Override
    public String toString() {
        return "" + major + "." + minor + "." + rev
                + (beta == Integer.MAX_VALUE ? "" 
                        : (beta == 1 ? "beta" : 
                            ("beta" + beta)));
    }


}

然后以标准的Java方式进行比较:

if (Version.parse(testFW).compareTo(Version.parse(baseFW)) < 0) {
   // Version is newer!
}