How does Ruby compare semantic version strings?
在比较Ruby字符串时,我注意到了一些意外的行为。我将在下面编写:
1 2 3 4 5 6 7 8 9 10 11 12 | 2.3.1 :011 > '5.6' >= '5.5' => true 2.3.1 :012 > '5.6' >= '5.7' => false 2.3.1 :013 > '5.6' >= '5.6.1' => false 2.3.1 :014 > '5.6' <= '5.6.1' => true 2.3.1 :016 > '4.6.1' <= '5.6' => true 2.3.1 :017 > '4.6.1' >= '5.6' => false |
我在几个地方在线看到人们正在使用
从以上测试中,我想我可以确认,这并不是简单地比较每个字符串的第一个/最后一个字符的ascii值。它也没有使用字符串长度作为我期望的主要比较。
它检查字符串中每个单独字符的序数。第一次在同一索引上不匹配时停止。序数越高,字符"越大"。基本上,它类似于:
1 | first_string.chars.map(&:ord) >= second_string.chars.map(&:ord) |
正如评论中指出的那样,这不会导致自然排序,因此人们为什么使用
1 | '11' > '9' # => false |
它正在比较纯字符串。
对于一个字符串的所有字符都位于第二个字符串的开头的字符串...但是如果第二个字符串的长度较长,则较短的字符串被认为小于。
否则,将一个一个地比较字符,直到一个字符串的" x"位置的字符与第二个字符串的" x"位置的字符不相等,在这种情况下,应考虑字母数字顺序中的较早字符小于
1 2 3 4 5 | 'cat' < 'caterpillar' => true 'cow' < 'caterpillar' => false |
如果版本号超过一位,则您不能依靠它来正确比较语义版本...所以
1 2 | '5.10' >= '5.9' => false |
(这不是人们希望的)