2013-07-02 23 views
3

我有紅寶石2.0.0p195(2013年5月14日修訂版40734)[x86_64的Linux的] 當我運行下面的代碼:String class'next!的奇怪行爲!上Unicode字符串方法

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] 
à 

但是,當我初始化字符來代替\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] 
ÀÈ 

爲什麼每種情況下的行爲如此不同?

+0

Unicode排序規則是複雜的東西,而string#succ自己做了一些複雜的東西(例如'z'.succ#=>「aa」)。兩者都不是簡單的,只要將1加到代碼點 –

回答

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,然後我們增加和轉換回。這很複雜,但它工作。