String类的奇怪行为'下一个! unicode字符串的方法

时间:2013-07-02 14:50:03

标签: ruby unicode

我有ruby 2.0.0p195(2013-05-14修订版40734)[x86_64-linux] 当我运行以下代码时:

char = "\u00D7"

(1..10).each {
    puts char.bytes.collect { |b| b.ord }.inspect
    puts char
    char.next!
}

我得到以下输出:

[195, 151]
×
[195, 152]
Ø
[195, 153]
Ù
[195, 154]
Ú
[195, 155]
Û
[195, 156]
Ü
[195, 157]
Ý
[195, 158]
Þ
[195, 159]
ß
[195, 160]
à

但是,当我将char初始化为\u00D6时,如下所示:

char = "\u00D6"

(1..10).each {
    puts char.bytes.collect { |b| b.ord }.inspect
    puts char
    char.next!
}

我得到以下内容:

[195, 150]
Ö
[195, 128, 195, 128]
ÀÀ
[195, 128, 195, 129]
ÀÁ
[195, 128, 195, 130]
ÀÂ
[195, 128, 195, 131]
ÀÃ
[195, 128, 195, 132]
ÀÄ
[195, 128, 195, 133]
ÀÅ
[195, 128, 195, 134]
ÀÆ
[195, 128, 195, 135]
ÀÇ
[195, 128, 195, 136]
ÀÈ

为什么每种情况下的行为都如此不同?

1 个答案:

答案 0 :(得分:0)

以下是我对这个问题的基本了解。

应根据unicode整理算法对Unicode字符进行排序。 Collation TableApparently,Ruby没有正确地执行此操作。我检查过以前的版本并遇到了同样的错误。排序规则也会影响next / succ方法。

为了获得适当的unicode排序规则,请尝试TwitterCLDR,其中包含排序排序规则的实现。

为了使您的原始代码按预期工作,请尝试使用此类

char = "\u00D6"

10.times do
    puts char.bytes.collect { |b| b.ord }.inspect
    puts char
    char = char.b.next.force_encoding("UTF-8")
end

b将字符串转换为ASCII-8BIT,然后我们递增并转换回来。这很复杂,但它确实有效。