`
fantaxy025025
  • 浏览: 1328357 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类

Ruby1.9之字符串内编码和外编码

 
阅读更多

这里的文章很不错的么:Rubyist

http://rubyeye.herokuapp.com/

 

puts "Encoding.default_external=#{Encoding.default_external}"
puts "Encoding.default_internal=#{Encoding.default_internal}"

  win7下默认输出:

Encoding.default_external=GBK

Encoding.default_internal=

 

 

From:http://rubyeye.herokuapp.com/articles/28-ruby1-9%E4%B9%8B%E5%AD%97%E7%AC%A6%E4%B8%B2%E5%86%85%E7%BC%96%E7%A0%81%E5%92%8C%E5%A4%96%E7%BC%96%E7%A0%81

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">&quot;</span><span class="content">r:UTF-8</span><span class="delimiter">&quot;</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)和源码

    - 字符串编码:Ruby 1.9引入了对多种字符编码的支持,使得处理多语言文本变得更加灵活。 - 更强的错误检测:在1.9版本中,语法错误和类型检查更加严格,减少了运行时错误。 - 全新的语法特性:如内建的块参数,...

    Programming Ruby 1.9

    1. **编码和字符集**:Ruby 1.9引入了对Unicode的全面支持,通过默认的内部编码(Encoding.default_internal)和外部编码(Encoding.default_external)来处理字符串。这使得处理多种语言和字符集变得更加容易。 2....

    Ruby-Unicode字符串调试帮助

    8. **调试工具**:除了Ruby自带的工具外,还可以利用IDE(如RubyMine)或文本编辑器(如VS Code)的内置调试功能,它们通常提供了查看字符串编码和字符结构的选项。 综上所述,Ruby在Unicode字符串处理方面提供了...

    Programming Ruby 1.9 The Pragmatic Programmers' Guide

    Ruby 1.9是Ruby的一个重要版本,引入了许多改进和新特性,包括性能优化、新的字符串编码系统、改进的模块和类的加载机制等。 在本书中,读者将学习到以下核心知识点: 1. **基础语法**:了解Ruby的基本数据类型,...

    ruby编码转换

    #### 二、强制更改字符串编码信息 虽然`force_encoding`方法可以更改字符串的编码信息,但需要注意的是,该方法并不会真正改变字符串内部的实际数据,只是更新了其编码标识。如果原字符串的数据与新设置的编码不...

    Pragmatic.rogramming.Ruby.1.9.and.2.0.4th.Edition.pdf

    例如,1.9版本引入了Unicode字符串处理,提高了对字符串编码的支持,使得开发者可以更好地处理多语言文本。此外,1.9对块和 Proc 对象的处理方式进行了改进,使得它们更易于理解和使用。而Ruby 2.0则带来了显著的...

    ruby1.9.1文档和一本pdf

    2. **编码处理**:Ruby 1.9 开始强制处理字符串的编码问题,每个字符串都有自己的编码类型,这大大增强了对多语言文本的支持。`encoding`关键字可用于声明源代码的编码。 3. **块和 Proc 对象**:Ruby 1.9 中,块...

    rsmaz:Smaz的Ruby端口-短字符串压缩库

    rsmaz (原始C版本)描述: Ruby的短字符串压缩。 RSmaz是Salvatore Sanfilippo的Smaz短字符串压缩算法的纯Ruby端口... decompress ( r ) Ruby 1.9和编码¶ ↑ RSmaz.compress始终返回具有二进制编码的字符串。 输入可

    国际化 - jcode库和$KCODE

    在Ruby中,处理UTF-8编码通常非常简单,因为它是Ruby默认的内部字符串编码。然而,当处理其他编码的数据时,我们需要确保正确的转换以避免乱码问题。 为了实现国际化,开发者通常会采用I18N(国际化的缩写,取自...

    Rubyist 1.9

    - **字符串编码**:默认使用UTF-8编码,增强了对多语言文本的支持。 - **符号和哈希**:符号可以作为哈希键,提高了效率和代码清晰度。 - **块和迭代器**:增强了块和迭代器的功能,使得代码更加简洁和模块化。 - **...

    ruby 1.9.3 p484稳定版本

    此外,1.9版本还引入了新的语法特性,如块的语法更简洁(使用'&'操作符),以及更强大的字符串字面量(如%q, %Q, %r等)。 在p484这个特定的补丁级别,开发者修复了大量已知问题,增强了稳定性和安全性。这意味着在...

    Ruby程序设计资料大全

    例如,它引入了全新的Unicode字符串编码支持,提高了对不同字符集的处理能力;新的语法结构,如内联字符串插值(String Interpolation)和模式匹配(Pattern Matching)提供了更高效的代码编写方式。 3. **面向对象...

    Ruby编程语言

    《Ruby编程语言》详细介绍了Ruby1.8和1.9版本各方面的内容。在对Ruby进行了简要的综述之后,《Ruby编程语言》详细介绍了以下内容:Ruby的句法和语法结构,数据结构和对象,表达式和操作符,语句和控制结构,方法、...

    magic_encoding:轻松管理 ruby​​ 1.9 应用程序编码的魔术注释

    我最初写这个是为了在在 rails 控制器上的 ruby​​ 中写入包含非 ascii 字符(如 éöàüèä)的字符串时摆脱“无效的多字节字符(US-ASCII)”错误 安装 gem install magic_encoding 用法 您可以使用像这样的...

    tdd-em-ruby-codigo-rspec:我的书“TDD em Ruby”的代码示例(http

    3. 字符串和符号的内部表示改变:Ruby 1.9中字符串和符号不再共享内存,这提高了内存管理效率,但同时也意味着字符串操作可能需要更多内存。 RSpec作为Ruby的主要测试库,其主要特点和知识点包括: 1. 行为驱动开发...

    ruby-1.9.3-preview1.zip

    1. **Unicode 支持**:Ruby 1.9 开始全面支持 Unicode 字符串,使得处理多语言文本变得更加容易。 2. **改进的性能**:通过优化内部实现,1.9.3 提升了运行速度,尤其是对于循环和字符串操作。 3. **更好的错误...

    绿色版 Ruby 1.9.2 For Windows 64 发布

    1. **字符串编码支持**:1.9.2开始支持Unicode编码,使处理多语言文本变得更加容易,为开发全球化应用提供了便利。 2. **块参数语法**:引入了新的块参数语法,允许更直观地处理代码块,如`|a, b|`,使得代码更加...

Global site tag (gtag.js) - Google Analytics