比较版本号的最佳灵活方法是什么?

时间:2010-03-01 21:08:43

标签: php versions string-comparison

我正在使用脚本来比较已安装和可用应用程序的版本号。我会在正常情况下使用简单的比较运算符。由于我在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环境中?

2 个答案:

答案 0 :(得分: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 // higher
              ^ 

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

    '5.1.6' < '5.2.12'
     5  1  6
     5  2  12 // higher
        ^

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

可能出现故障的版本是5.2-alpha-foo与5.2.49.4-beta-bar之类的版本,您必须将纯数字子字符串与字母数字子字符串进行比较:

    5.2-alpha-foo > 5.2.49.9.-beta-bar
    5  2  alpha  foo ----  ---  // wrong - ascii 65(a) vs 52(4)
    5  2  49     4   beta  bar
          ^

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

答案 1 :(得分:0)

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

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

这有缺陷: 1.2.3rc1&gt; 1.2.3 1.2.3alpha> 1.2.3 ,这可能不对

相关问题