Ruby1 9之字串內編碼和外編碼

2021-09-02 11:55:00 字數 4102 閱讀 3597

puts "encoding.default_external=#"

puts "encoding.default_internal=#"

win7下預設輸出:

encoding.default_external=gbk

encoding.default_internal=

ruby1.9的字串編碼改動非常大。在ruby1.8,每個字串都是位元組序列,沒有字元的概念。唯一乙個和字元編碼有關的$kcode可以指定全域性的編碼。 但是$kcode對字串編碼的改變很小,因為$kcode只做了這樣幾件事:

影響inspect

ree-1.8.7-2011.03 :016 > $kcode = "a"

=> "a"

ree-1.8.7-2011.03 :017 > p "

résumé""

r\303

\251

sum\303

\251

" => nil

ree-1.8.7-2011.03 :01

8 > p "你好"

"\344

\275

\240

\345

\245

\275

" => nil

ree-1.8.7-2011.03 :01

9 > $kcode = "u"

=> "u"

ree-1.8.7-2011.03 :020 > p "你好"

"你好" => nil

ree-1.8.7-2011.03 :021 > p "

résumé""

résumé

" => nil

影響正則:

ree-1.8.7-2011.03 :027 > $kcode = "a"

=> "a"

ree-1.8.7-2011.03 :02

8 > "你好"

.scan(/./

) => ["

\344

", "

\275

", "

\240

", "

\345

", "

\245

", "

\275"]

ree-1.8.7-2011.03 :030 > $kcode = "u"

=> "u"

ree-1.8.7-2011.03 :031 > "你好"

.scan(/./

) => ["你"

, "好

"]

並且,$kcode是乙個全域性的變數,它對所有檔案產生作用,這在你的程式裡引入了第三方庫,時候會遇到麻煩。

ruby1.9對字元編碼的控制分的很細:

[h1]原始檔編碼[/h1]

ruby1.9裡,所有的字串字面量都由字串行+編碼標識組成。 可以通過乙個magick comment(# encoding: utf-8)來宣告源**裡的字串字面量的編碼標識。這個comment針對每個檔案起作用,不像1.8的$kcode是在全域性起作用。可以通過force_encoding方法來改變字元的編碼標識(force_encoding並未轉換編碼,只改變標識)

# encoding: gbk

puts encoding

#=> gbk

puts "

".encoding #=> gbk

str = "你好"

.force_encoding "

utf-8

"puts str.encoding # => utf-8

雖然force_encoding只改變了字元的編碼標識,沒有改變位元組序列,但是,隨著字串的編碼標識的改變,字串的一些行為也跟著改變,比如inspect和each_char:

ruby-1.9.3-rc1 :017 > str = "你好"

=> "你好"

ruby-1.9.3-rc1 :01

8 > p str.encoding

# => #

ruby-1.9.3-rc1 :01

9 > str.each_char

—> #"

}"你—> 3""

好—> 3

" => "你好"

ruby-1.9.3-rc1 :020 > str.force_encoding "

gbk"

=> "

\x\x\x"

ruby-1.9.3-rc1 :021 > str.each_char

—> #"

}"\x—> 2""

\x—> 2""

\x—> 2

" => "

\x\x\x"

ruby-1.9.3-rc1 :022 >

[h1]外部編碼[/h1] 字串的**可能有兩種,一種是前面提到的原始檔,另外一種是從外部io讀取到的。 對於第一種我們可以直接通過magick comment來設定字串的預設編碼標識。而從外部io讀取到的字元編碼標識是通過io物件的external_encoding和internal_encoding來設定的。

hooopohooopo

:~/rubyist$ cat show_external_encoding.rb

open(__file__, "

r:utf-8

") do |file|

puts file.external_encoding.name

p file.internal_encoding

file.each do |line|

p [line.encoding.name, line]

endendhooopohooopo

:~/rubyist$ ruby show_external_encoding.rb

utf-8

nil["

utf-8

", "

open(file,

\"r:utf-8

\") do |file|\n"

]["utf-8

", "

puts file.external_encoding.name\n"

]["utf-8

", "

p file.internal_encoding\n"

]["utf-8

", "

file.each do |line|\n"

]["utf-8

", "

p [line.encoding.name, line]\n"

]["utf-8

", "

end\n"]

["utf-8

", "

end\n

"]

上面的例子展示了,通過設定io物件的外部編碼,使讀取過來的字串有了預設的編碼標識。

加上內編碼的情況就更繞了:

io物件設定了內編碼以後,會自動幫你把讀來的字串從外編碼轉換成內編碼。即:

iconv.iconv(internal_encoding, external_encoding, str)

如果io物件的internal encoding和external encoding沒有設定,他們會繼承自encoding.default_external 和 encoding.default_internal

+==+

==

Ruby 1 9以後字串編碼方式的變化

在某次為專案的乙個應用程式memy做rake測試時出現了如下的錯誤 root rp1 memy3.0.7 rake trace error info rake aborted var qup memy3.0.7 thinking sphinx ruby 1.9.1 gems jieks 0.0.6 ...

字串和編碼

編碼 ascii unicode utf 8 ascii編碼和unicode編碼的區別 ascii編碼是1個位元組,而unicode編碼通常是2個位元組。utf 8編碼把乙個unicode字元根據不同的數字大小編碼成1 6個位元組,常用的英文本母被編碼成1個位元組,漢字通常是3個位元組,只有很生僻的...

Python隨筆之字串和編碼

字串是一種我們平時使用比較多的型別,字串和其他資料型別相比有個特殊的問題,令我們比較頭疼的問題,那就是編碼問題。因為計算機只能處理數字,如果需要處理文字,就需要將其轉換為數字後才能處理。最早計算機在設計的時候採用的是8位 位元 bit 二進位制為乙個位元組 byte 所以乙個位元組能表示的最大的數就...