Ruby:字符集和编码学习总结
2013-08-22 23:59
260 查看
背景
Ruby直到1.9版本才很好的支持了多字节编码,本文简单总结了今天学习的关于Ruby编码方面的知识。字符串可以使用不同的编码
在.NET中字符串的编码是一致的,Ruby允许字符串有不同的编码,当时我就在想:如果两个不同编码的字符串相加会出现什么结果?测试程序
# coding: utf-8 str_utf8 = "hi 段" puts str_utf8.size # 4 puts str_utf8.bytesize # 6 puts str_utf8 .encoding # UTF-8 str_utf8.each_byte {|b| print "%02X," % } # 68,69,20,E6,AE,B5, puts puts str_gb2312 = "hi 段".encode("gb2312") puts str_gb2312.size # 4 puts str_gb2312.bytesize # 5 puts str_gb2312 .encoding # GB2312 str_gb2312.each_byte {|b| print "%02X," % [b]} # 68,69,20,B6,CE, puts
[b]输出结果
4 6 UTF-8 68,69,20,E6,AE,B5, 4 5 GB2312 68,69,20,B6,CE,
备注:UTF-8对英文采用1个字节,对中文采用三个字节。GB2312对英文采用1个字节,对中文采用两个字节。
编码转换
编码转换可以采用String::encode("目标编码名称")来完成,如果编码之间的转换兼容,返回编码后的字符串,否则会抛出编码转换异常。测试程序
begin puts "段".encode("ascii") rescue Exception => e puts e.class end puts "段".encode("gb2312")
输出结果
Encoding::UndefinedConversionError 段
备注:encode会返回一个和元字符串序列一样的字符串序列,只是内部的字节序列改变了。
编码强制
编码强制是指在不改变字节序列的情况下改变对字节的解释方式,编码强制:String::force_encoding("强制编码")。测试程序
utf8_str = "\xE6\xAE\xB5".encode("utf-8") puts utf8_str.encoding() # UTF-8 puts utf8_str.size # 1 puts utf8_str.bytesize # 3 ascii_str = "\xE6\xAE\xB5".force_encoding("ascii") puts ascii_str.encoding() # US-ASCII puts ascii_str.size # 3 puts ascii_str.bytesize # 3 puts ascii_str.valid_encoding? # false
输出结果
UTF-8 1 3 US-ASCII 3 3 false
备注:String::valid_encoding?可以判定是否是有效的强制。
不同编码的字符串相加后是啥结果?
这个问题的答案很简单:如果两个字符串的编码兼容,则返回字符集最大的编码,否则跑出不兼容异常。你可以自己检查兼容性:Encoding.compatible?。测试程序
str_ascii = "hi ".encode("ascii") str_utf8 = "段" puts str_ascii.encoding puts str_utf8.encoding puts Encoding.compatible?(str_ascii.encoding, str_utf8.encoding) puts (str_ascii + str_utf8).encoding puts (str_utf8 + str_ascii).encoding
运行结果
US-ASCII UTF-8 UTF-8 UTF-8 UTF-8
一直没使用过的\u和\x
几乎所有的语言都支持这两个转义字符,允许我们使用\uXXXX指定Unicode码点对于的字符,通用也运行我们使用\xXX指定字节。测试程序
puts "段" # 段 puts "\xE6\xAE\xB5" # 段 puts "\u6BB5" # 段
输出结果
# 段 # 段 # 段
使用Sublime开发Ruby时,输出到控制台的字符串为啥不能使用多种编码?
测试程序puts "段" puts "段".encode("GB2312")
在Sublime中的输出结果
[Decode error - output not utf-8]
在控制台的输出结果
原因分析
Sublime之所以失败是因为Sublime重定位了默认标准输出流,而重定位后的流不支持混合多种编码,说白了:你没法在一个文件中保存两种编码的字符串。
备注:Sublime中的失败不是Ruby导致的,是Sublime自身的问题。
如何解决?
Sublime默认只能接收UTF8编码,因此必须转换为UTF8编码。
# 默认是UTF8编码,不用处理。 puts "段" # 执行windows命令必须使用GB2312编码。 command = "echo 段".encode("GB2312") # 命令执行的结果想输出到Sublime必须使用UTF8编码。 puts `#{command}`.encode("utf-8")
输出结果
# 输出结果 段 段
备注
字符串、字符集和编码算是刚入门,有机会还得继续学习。相关文章推荐
- .NET:字符集和编码学习总结
- 字符集编码以及java乱码问题学习总结
- 字符集和编码学习总结
- [Ruby学习总结]Ruby语言的语法
- java基础学习总结二(标识符、字符集、数据类型以及类型转换)
- 软件工程(C编码实践篇)学习总结
- java web 学习笔记 编码问题总结
- 软件工程(C编码实践篇)学习总结
- 软件工程(C编码实践篇)学习总结
- 软件工程(C编码实践篇)学习总结
- GDI+学习及代码总结之------图像的编码与解码
- 软件工程(C编码实践篇)学习总结
- 软件工程(C编码实践篇)学习总结
- java web 学习笔记 编码问题总结
- 软件工程(C编码实践篇)学习总结
- 软件工程(C编码实践篇)学习总结
- Eclipse rap 富客户端开发总结(8) - 发布到tomcat后解决rap编码和字符集的问题
- 高级软件工程&&《软件工程(C编码实践篇)》课程学习心得及内容总结
- 正则表达式中对各字符集编码范围的总结
- 正则表达式中对各字符集编码范围的总结