锁定老帖子 主题:UTF8编码和正则表达式
该帖已经被评为良好帖
|
|
---|---|
作者 | 正文 |
发表时间:2009-04-21
呃,楼上的童鞋,你应该去看看1.9了。
|
|
返回顶楼 | |
发表时间:2009-04-21
oCameLo 写道 呃,楼上的童鞋,你应该去看看1.9了。
为什么呢?现在1.9的库还不是很成熟呀。。 |
|
返回顶楼 | |
发表时间:2009-04-21
最后修改:2009-04-21
所谓不成熟,看你用不用得到了,我平常会用到的好像就只有sqlite3还有问题。
1.9加了些很不错的东西,string方面虽然还不能让人满意,但也总是有改进,看看这个:http://otnth.blogspot.com/2009/04/unicode-in-ruby-19.html |
|
返回顶楼 | |
发表时间:2009-04-21
oCameLo 写道 所谓不成熟,看你用不用得到了,我平常会用到的好像就只有sqlite3还有问题。
1.9加了些很不错的东西,string方面虽然还不能让人满意,但也总是有改进,看看这个:http://otnth.blogspot.com/2009/04/unicode-in-ruby-19.html Ruby 1.9终于抛弃了丑陋的jcode,提供一定程度上的Unicode支持。只不过我总觉得有点儿不对劲,Ruby当前采用的处理方式,很可能会带来一些新的问题。 String有了encoding属性,部分方法的处理单位也由字节改为字符。源码文件的默认编码为US-ASCII,如果在代码中写了中文,就必须指定encoding。如果不想写,也可以用BOM。 # encoding: utf-8 s = '幺贰和叁' puts s.encoding # => UTF-8 puts s.length # => 4 puts s.bytesize # => 12 不同encoding字符串之间可以直接比较,也就是说从今以后比较字符串都要考虑编码问题,搞不好会有很多Bug因此而产生。 # encoding: utf-8 s = '位'.encode('gbk') t = 'λ' puts s.bytes.to_a == t.bytes.to_a # => true puts s == t # => false puts s == t.force_encoding('gbk') # => true 正则表达式方面更乱,encoding不同“=~”一定会报错,但match方法却不一定。 # encoding: utf-8 s = 'abc'.encode('gbk') p s.match(/b/) # => #<MatchData "b"> s =~ /b/ # => incompatible encoding regexp match (UTF-8 regexp with GBK string) (Encoding::CompatibilityError) s = '位'.encode('gbk') p s.match('λ') # => incompatible encoding regexp match (UTF-8 regexp with GBK string)(Encoding::CompatibilityError) IO方面也添加了encoding支持,不过还不支持BOM,所以读取带BOM的文件得多一个步骤。 File.open('utf8_with_bom.txt', 'r:utf-8') do |f| f.ungetc c unless (c = f.getc)=="\uFEFF" # ... end Python 3.0中一个很大的变化就是区分了String和Byte,所有String都是Unicode,说不定有一天Ruby也会走Python的老路,希望这只是我乌鸦嘴吧。 我觉得上面说的1.9的问题没什么的,既然可以判断编码方式了,不同编码方式的比较前只要判断一下就可以的,是可以控制的。而正则表达式也是一样,既然能判断编码方式,也能转换,这有什么问题呢? |
|
返回顶楼 | |
发表时间:2009-04-21
oCameLo 写道 所谓不成熟,看你用不用得到了,我平常会用到的好像就只有sqlite3还有问题。
1.9加了些很不错的东西,string方面虽然还不能让人满意,但也总是有改进,看看这个:http://otnth.blogspot.com/2009/04/unicode-in-ruby-19.html 1.9我以前用过,感觉在处理字符方面真的比1.86要舒服很多。 您是用ruby来做什么的? |
|
返回顶楼 | |
发表时间:2009-04-22
最后修改:2009-04-22
呃,我拿ruby来干杂事。。
你转的这篇东西里还有几个问题没提到,Net::HTTP抓回来的东西默认编码是ASCII-8BIT,File.open('test.txt').read.encoding在Windows里又是GBK。 这些问题的确只要小心一点都可以避免,但一直都要很小心不也挺麻烦的。比如说检查字符串,难道都得写m == n and m.encoding == n.encoding? 预先检查并统一字符串编码可能可以解决一部分问题,但这样的话在每一个类每一个模块里都要干同样的事,还是又啰嗦又容易出错。 更何况别忘了,咱们中国人被编码问题蹂躏得够久,可西方人向来是不在乎这些的。在他们写的库里会遇到编码问题,几乎肯定是会发生的事。 我对1.9的了解其实不多,不知道ruby对这些问题有没有预防性的措施。不过就我看到的用到的东西来说,总觉得日后会麻烦一堆。 插个花,按说ruby帮老大是日本人,不应该会有这种问题才对。可是ruby一开始就没有支持Unicode的打算,现在又整这么一出,再加上性能问题GC问题,大着胆子说一句,有时候还真有些怀疑那谁的眼光和能力。 |
|
返回顶楼 | |
发表时间:2009-04-22
呃,我拿ruby来干杂事。。
引用 你转的这篇东西里还有几个问题没提到,Net::HTTP抓回来的东西默认编码是ASCII-8BIT,File.open('test.txt').read.encoding在Windows里又是GBK。
这个我还真没注意,因为在1.86中没有检查字符编码的方法,不像1.9,str.encoding=>ascii8bit 刚才试了一下确实Het::HTTP返回的string的encoding是ASCII-8BIT,而且open-uri也一样。 但是我已经说了,在1.86中字符串的默认处理方式(不设置$KCODE的情况下)就是ASCII-8BIT,即便用iconv转换成utf-8,ruby在内存中也是按照字节方式去解析的。比如: irb(main):046:0> h.size => 35113 irb(main):047:0> h.scan(/./).size => 34728 irb(main):048:0> h.scan(/./u).size => 29228 引用 这些问题的确只要小心一点都可以避免,但一直都要很小心不也挺麻烦的。比如说检查字符串,难道都得写m == n and m.encoding == n.encoding?
预先检查并统一字符串编码可能可以解决一部分问题,但这样的话在每一个类每一个模块里都要干同样的事,还是又啰嗦又容易出错。 这个当然不必要这样做。不是可以这样嘛:#encoding :utf-8 当然如果是网络或从其他文件读取的内容可以强制转换一下s.force_encoding("utf-8") 这样不就都统一了嘛,比1.8.6要舒服不知道多少倍。 引用 更何况别忘了,咱们中国人被编码问题蹂躏得够久,可西方人向来是不在乎这些的。在他们写的库里会遇到编码问题,几乎肯定是会发生的事。
我对1.9的了解其实不多,不知道ruby对这些问题有没有预防性的措施。不过就我看到的用到的东西来说,总觉得日后会麻烦一堆。 插个花,按说ruby帮老大是日本人,不应该会有这种问题才对。可是ruby一开始就没有支持Unicode的打算,现在又整这么一出,再加上性能问题GC问题,大着胆子说一句,有时候还真有些怀疑那谁的眼光和能力。 现在编码不是问题了,gc不太清楚。。其实1.9最大的问题是很多库都没跟上来。 |
|
返回顶楼 | |
发表时间:2009-04-22
#encoding只对当前文件有效。
按理说跟所有外部模块和类传递的字符串在使用前都需要检查编码,而你可以这样做,写模块和类的人未必会这样做,所以我才说又麻烦又容易出错。 当然了,问题是可以解决的。首先自己小心一点,如果别人不小心,代码拿来改就是了。不当他是问题,当然就不是问题,1.8这么些年还不是照样用得好好的。 |
|
返回顶楼 | |
发表时间:2009-04-22
oCameLo 写道 这些问题的确只要小心一点都可以避免,但一直都要很小心不也挺麻烦的。比如说检查字符串,难道都得写m == n and m.encoding == n.encoding? 不用比较 encoding 的。 oCameLo 写道 预先检查并统一字符串编码可能可以解决一部分问题,但这样的话在每一个类每一个模块里都要干同样的事,还是又啰嗦又容易出错。 magic column 可以解决一部分啰嗦的问题。 不满意的地方就自己打开 String 修改,基本不会啰嗦。 oCameLo 写道 插个花,按说ruby帮老大是日本人,不应该会有这种问题才对。可是ruby一开始就没有支持Unicode的打算,现在又整这么一出,再加上性能问题GC问题,大着胆子说一句,有时候还真有些怀疑那谁的眼光和能力。 普遍性能是变好了,西方人可能不爽:string 更适合处理多字节字符了,但处理纯 ascii 会慢很多。 特定场景会差一些,而性能…… 等你的算法优化到极限了再来谈性能吧…… 闹得沸沸扬扬的 GC 问题不是补丁上了么? 虽然落后、破烂,但是它能工作,很了不起了。 不信可以自己实现个 ruby,感受一下…… |
|
返回顶楼 | |
发表时间:2009-04-22
只要一沾带中文的 都那么麻烦
|
|
返回顶楼 | |