这里的文章很不错的么:Rubyist
puts "Encoding.default_external=#{Encoding.default_external}" puts "Encoding.default_internal=#{Encoding.default_internal}"
win7下默认输出:
Encoding.default_external=GBK
Encoding.default_internal=
Ruby1.9之字符串内编码和外编码
Ruby1.9的字符串编码改动非常大。在Ruby1.8,每个字符串都是字节序列,没有字符的概念。唯一一个和字符编码有关的$KCODE可以指定全局的编码。 但是$KCODE对字符串编码的改变很小,因为$KCODE只做了这样几件事:
- 让ruby解析器按照$KCODE的编码方式解析源代码
- 让inspect方法按$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\251sum\303\251" => nil ree-1.8.7-2011.03 :018 > p "你好" "\344\275\240\345\245\275" => nil ree-1.8.7-2011.03 :019 > $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 :028 > "你好".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 :018 > p str.encoding #<Encoding:UTF-8> => #<Encoding:UTF-8> ruby-1.9.3-rc1 :019 > str.each_char{|x| p "#{x}—> #{x.bytesize}"} "你—> 3" "好—> 3" => "你好" ruby-1.9.3-rc1 :020 > str.force_encoding "GBK" => "\x{E4BD}\x{A0E5}\x{A5BD}" ruby-1.9.3-rc1 :021 > str.each_char{|x| p "#{x}—> #{x.bytesize}"} "\x{E4BD}—> 2" "\x{A0E5}—> 2" "\x{A5BD}—> 2" => "\x{E4BD}\x{A0E5}\x{A5BD}" ruby-1.9.3-rc1 :022 >
[h1]外部编码[/h1] 字符串的来源可能有两种,一种是前面提到的源文件,另外一种是从外部IO读取到的。 对于第一种我们可以直接通过magick comment来设置字符串的默认编码标识。而从外部IO读取到的字符编码标识是通过IO对象的external_encoding和internal_encoding来设置的。
hooopohooopo</span><span class="symbol">:~</span>/rubyist<span class="error">$</span> cat show_external_encoding.rb
open(<span class="predefined-constant">__FILE__</span>, <span class="string"><span class="delimiter">"</span><span class="content">r:UTF-8</span><span class="delimiter">"</span></span>) <span class="keyword">do</span> |file|
puts file.external_encoding.name
p file.internal_encoding
file.each <span class="keyword">do</span> |line|
p [line.encoding.name, line]
<span class="keyword">end</span>
<span class="keyword">end</span>
hooopo<span class="instance-variable">
hooopo:~/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对象的外部编码,使读取过来的字符串有了默认的编码标识。
加上内编码的情况就更绕了:
cat show_internal_encoding.rb open("baidu.html", "r:GBK:UTF-8") do |file| puts file.external_encoding.name p file.internal_encoding file.each do |line| p [line.encoding.name, line[100..200]] end end ruby show_internal_encoding.rb GBK #<Encoding:UTF-8> ["UTF-8", ">百度一下,你就知道
IO对象设置了内编码以后,会自动帮你把读来的字符串从外编码转换成内编码。即:
Iconv.iconv(internal_encoding, external_encoding, str)
如果IO对象的internal encoding和external encoding没有设置,他们会继承自Encoding.default_external 和 Encoding.default_internal
参考资源:
+
=
=
+
=
=
相关推荐
Programming Ruby 1.9 (3rd edition)和源码
Programming Ruby 2.0 1.9 pdf
NULL 博文链接:https://hlee.iteye.com/blog/599644
本资源是ruby代码,提供了一系列封装好的函数,用于快速进行转换,一个函数搞定,包括如下转换,二进制字符串与hex字符串的互转。二进制字符串与整数互转,包括uint8,uin16,uint32, 以及本地字节序和网络字节序两种...
Programming Ruby 1.9 3rd edition.Cover ruby 1.9.2, downloaded from pragmatic bool shelf, please enjoy.
Programming Ruby 1.9 The Pragmatic Programmers' Guide -- Ruby 编程的圣经教程。此版本涵盖最新的Ruby 1.9
Programming Ruby 1.9
This book is the only complete reference for both Ruby 1.9 and Ruby 2.0, the very latest version of Ruby. 2013 marks the 20th anniversary of the Ruby language. We’re proud that throughout its history...
ruby 1.9上的轻量级网络开发框架,提供generator!
[Pragmatic Bookshelf] Ruby 1.9 & 2.0 编程 (英文版) [Pragmatic Bookshelf] Programming Ruby 1.9 & 2.0 The Pragmatic Programmers' Guide 4th Edition (E-Book) ☆ 出版信息:☆ [作者信息] Dave Thomas , ...
一些Ruby程序员将Ruby 1.9的发布看做是迈入Ruby新版本的标志性事件,但他们却发现在1.8版本和1.9版本语言之间的刻意不兼容性会导致原有Ruby代码无法工作。真正的问题是,Ruby 1.9.0发布的原因以及其与Ruby1.8之间的...
2009年的新书--Programming Ruby 1.9
最新的ruby 教程 2009 年 ruby 已经发展到了1.9 2.0要到2010年了
Ruby编程语言_涵盖Ruby 1.8和1.9
《Ruby程序设计语言》是Ruby的权威指南,全面涵盖该语言的1.8版和1.9版。本书详尽但并不拘泥于语言规范,既适合首次接触Ruby的资深程序员,同样也适合那些想要挑战对这门语言的理解并更深入掌握它的Ruby程序员。本书...
Ruby的Block块是它的关键特色之一,用块能够写出简明且高度可重用的算法。即使没有别的用处,它至少消弱了人们对循环敬畏的态度。这个概念在其他语言和理论中还被称为:Lambda函数。Lambda是个十分令人迷惑的词汇,...
Programming Ruby 1.9 3rd Edition – FreePdfBook
Unicode字符串调试帮助