背景

Ruby直到1.9版本才很好的支持了多字节编码,本文简单总结了今天学习的关于Ruby编码方面的知识。

字符串可以使用不同的编码

在.NET中字符串的编码是一致的,Ruby允许字符串有不同的编码,当时我就在想:如果两个不同编码的字符串相加会出现什么结果?

测试程序

 # coding: utf-8

 str_utf8 = "hi 段"
puts str_utf8.size #
puts str_utf8.bytesize #
puts str_utf8 .encoding # UTF-8
str_utf8.each_byte {|b| print "%02X," % [b]} # 68,69,20,E6,AE,B5,
puts puts str_gb2312 = "hi 段".encode("gb2312")
puts str_gb2312.size #
puts str_gb2312.bytesize #
puts str_gb2312 .encoding # GB2312
str_gb2312.each_byte {|b| print "%02X," % [b]} # 68,69,20,B6,CE,
puts

输出结果

 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 #
puts utf8_str.bytesize # ascii_str = "\xE6\xAE\xB5".force_encoding("ascii")
puts ascii_str.encoding() # US-ASCII
puts ascii_str.size #
puts ascii_str.bytesize #
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")

输出结果

  # 输出结果

备注

字符串、字符集和编码算是刚入门,有机会还得继续学习。

Ruby:字符集和编码学习总结的更多相关文章

  1. .NET:字符集和编码学习总结

    背景 一直没有深入的学习字符集和编码的知识(现在也没有深入),今天查阅了一些资料,弄明白了一些事情,本文就简单记录一下. 字符集和编码 字符集是指一些符号组成的集合,编码是对指定字符集如何表示为字节的 ...

  2. WEB开发中的字符集和编码

    html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,bi ...

  3. java中的字符集和编码

    前言 上次对计算机中的“字符集”和“编码”分别进行了总结,并指出二者之间的区别,不要搞混了,不清楚的再回到上一章看一下.今天再总结下java中是如何使用字符集(主要是Unicode字符集,其他常用字符 ...

  4. Linux字符集和编码

    计算机内部,所有信息最终都是一个二进制值形式存放 字符集 字符集:charset是character set的简写,即二进制和字符的对应关系,不关注最终的存储形式 编码 字符集编码:encoding是 ...

  5. C#和VC++字符集和编码

    C# char 关键字用于声明 .NET framework 使用 Unicode 字符表示 System.Char 结构的实例. Char 对象的值是 16 位数字 (序号值.)将字符表示为 UTF ...

  6. Unicode字符集和编码方式

    通常将一个标准中能够表示的所有字符的集合称为字符集,比如ISO/Unicode所定义的字符集为Unicode.在Unicode中,每个字符占据一个码位/Unicode 编号(用4位十六进制数表示,Co ...

  7. 字符集和编码——Unicode(UTF&UCS)深度历险

    计算机网络诞生后,大家慢慢地发现一个问题:一个字节放不下一个字符了!因为需要交流,本地化的文字需要能够被支持. 最初的字符集使用7bit来存储字符,因为那时只需要存下一些英文字母和符号.后来虽然扩展到 ...

  8. 字符编码和字符集和编码引出的问题_FileReader读取GBK格式的文件

    字符编码 计算机中鵆的信息都是用二进制数表示的,而我们在屏幕上看到的数字.英文.标点符号.汉子等字符都是二进制数转换之后的结果.按照某种规则,将字符存储到计算机中,称为编码.反之,将存储在计算机中的二 ...

  9. 字符集和编码II: fat/msdos/vfat (文件名乱码的问题)

    具体到文件名乱码的问题,需要明确两点 第一,文件名作为一个字符串,需要被编码后存入文件系统: 第二,Linux内核无非是个特殊的应用程序,它读取文件名,再把文件名以编码后的形式传递出去. 但Linux ...

随机推荐

  1. IOS-优质应用推荐

    壁纸应用 cuto 免费 点击下载 shots 收费 点击下载 Cutisan 锁屏壁纸制作下载地址 待办事项 TodayMind - 提醒事项触手可及 点击下载 滴答清单 点击下载 Microsof ...

  2. Jenkins+Ant+SVN+Jmeter实现持续集成

     一.什么是持续集成? 待补充 二.说明: 本次框架介绍中不涉及到介绍框架的构建过程,介绍如何构建环境详细的构建见前篇文章: jmeter+Jenkins持续集成(邮件通知) Jmeter+Jenki ...

  3. Q:WCHAR转化为CHAR

    A: int len =WideCharToMultiByte(CP_ACP,0,此处是WCHAR的参数,-1,NULL,0,NULL,NULL); WideCharToMultiByte(CP_AC ...

  4. C# asp.net 实现导出Excel

    原文地址:传送门 这段时间用到了导出Excel的功能,这个功能还是比较常用的,我常用的有两个方法,现在整理一下,方便以后查看. 1.实现DataTable数据导出到本地,需要自己传进去导出的路径. / ...

  5. lr_get_attrib_string的使用

    loadrunner controller 传递参数的一个方法: lr_get_attrib_string lang  =    lr_get_attrib_string("lang&quo ...

  6. list 移除值

    1. 移除基本类型值时,传入int 会以下标为依据移除 , 但传入Integer 对象时,则是移除对象为依据移除(即不受此对象代表的值相等的下标的影响) 都是只能移除一个值,(list 中有多个1时, ...

  7. cdoj1092-韩爷的梦 (字符串hash)【hash】

    http://acm.uestc.edu.cn/#/problem/show/1092 韩爷的梦 Time Limit: 200/100MS (Java/Others)     Memory Limi ...

  8. FastReport.Net使用:[22]地图(Map)控件

    标记有学生地区 1.在报表中放一个地图控件 将地图控件放在标题区即可,其他栏目删除. 2.双击地图控件进行地图添加. 可以再网上下载到地图数据,ESRI shapefile文件,本例中找了个省会城市地 ...

  9. POJ 1498[二分匹配——最小顶点覆盖]

    题目链接:[http://acm.hdu.edu.cn/showproblem.php?pid=1498] 题意:给出一个大小为n*n(0<n<100)的矩阵,矩阵中放入m种颜色(标号为1 ...

  10. BZOJ4599[JLoi2016&LNoi2016]成绩比较(dp+拉格朗日插值)

    这个题我们首先可以dp,f[i][j]表示前i个科目恰好碾压了j个人的方案数,然后进行转移.我们先不考虑每个人的分数,先只关心和B的相对大小关系.我们设R[i]为第i科比B分数少的人数,则有f[i][ ...