1

我正在使用脚本来比较已安装和可用应用程序的版本号。在正常情况下,我会使用简单的比较运算符。由于我在 PHP 5.3 环境中构建此应用程序,因此我考虑过使用version_compare(),但这似乎并不像我想要的那样干净地满足我的需求。

我正在比较的版本字符串可以遵循多种格式,但到目前为止我遇到的是:

  • “2.6.18-164.6.1.el5”与“2.6.18-92.1.13.el5”
  • “4.3p2”与“5.1p1”
  • “5.1.6”与“5.2.12”
  • '2.6.24.4-foo.bar.x.i386' 与 '2.4.21-40'

如您所见,我确实没有一致的格式可以使用。

我考虑做的一件事是将每个版本字符串拆分为非数字字符,然后迭代生成的数组并比较相对索引。但是,我不确定这是否是一种好方法,尤其是在 '2.6.24-4-foo.a.12.i386' 与 '2.6.24-4-foo.b.12' 的情况下.i386'。

是否有任何经过充分测试的方法来比较非常松散的版本号,特别是在 PHP 环境中?

4

2 回答 2

2

按符号拆分(请参阅preg_split)并以数字方式比较每个元素(如果两者都是数字)或使用字符串比较(当两者都是字母数字时)适用于您的示例:

    '2.6.18-164.6.1.el5' > '2.6.18-92.1.13.el5'
    2 6 18 164 6 1 e15
    2 6 18 92 1 13 e16 // 更高
              ^

    '4.3p2' < '5.1p1'
    4 3 p2
    5 1 p1 // 更高
    ^

    '5.1.6' < '5.2.12'
     5 1 6
     5 2 12 // 更高
        ^

    '2.6.24.4-foo.bar.x.i386' > '2.4.21-40'
     2 6 24 4 foo bar x i386 // 更高
     2 4 21 40 --- --- - ----
        ^

它可能失败的地方是 5.2-alpha-foo vs 5.2.49.4-beta-bar 之类的版本,您必须将纯数字子字符串与字母数字子字符串进行比较:

    5.2-alpha-foo > 5.2.49.9.-beta-bar
    5 2 alpha foo ---- --- // 错误 - ascii 65(a) vs 52(4)
    5 2 49 4 贝塔棒
          ^

每当您将纯数字子字符串与字母数字子字符串进行比较时,您可以通过将字母数字字段视为 0 来解决此问题。

于 2010-03-01T21:31:56.720 回答
0

作为参考 rpm 比较版本字符串,如下所示:

  • 拆分所有非字母数字字符
  • 将连续的数字字符组合在一起,将所有非数字字符组合在一起(即 1.12.ab002 拆分为 1、12、ab、002)
  • 从左到右比较每个组
    • 如果两个版本都有数字组,则将它们作为数字进行比较(即 1 = 001 和 12 > 5)
    • 如果其中一个是非数字组,则执行简单的字符串比较
  • 第一个不等比较是结果
  • 更长的版本被认为更大(即 1.2.3 < 1.2.3.0 和 alp < alpha)

这有缺陷:1.2.3rc1 > 1.2.31.2.3alpha > 1.2.3这可能不正确

于 2010-03-01T22:04:06.937 回答