论坛首页 编程语言技术论坛

UTF8编码和正则表达式

浏览 25214 次
该帖已经被评为良好帖
作者 正文
   发表时间:2009-04-21  
呃,楼上的童鞋,你应该去看看1.9了。
0 请登录后投票
   发表时间:2009-04-21  
oCameLo 写道
呃,楼上的童鞋,你应该去看看1.9了。

为什么呢?现在1.9的库还不是很成熟呀。。
0 请登录后投票
   发表时间:2009-04-21   最后修改:2009-04-21
所谓不成熟,看你用不用得到了,我平常会用到的好像就只有sqlite3还有问题。

1.9加了些很不错的东西,string方面虽然还不能让人满意,但也总是有改进,看看这个:http://otnth.blogspot.com/2009/04/unicode-in-ruby-19.html
0 请登录后投票
   发表时间: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的问题没什么的,既然可以判断编码方式了,不同编码方式的比较前只要判断一下就可以的,是可以控制的。而正则表达式也是一样,既然能判断编码方式,也能转换,这有什么问题呢?

0 请登录后投票
   发表时间:2009-04-21  
oCameLo 写道
所谓不成熟,看你用不用得到了,我平常会用到的好像就只有sqlite3还有问题。

1.9加了些很不错的东西,string方面虽然还不能让人满意,但也总是有改进,看看这个:http://otnth.blogspot.com/2009/04/unicode-in-ruby-19.html

1.9我以前用过,感觉在处理字符方面真的比1.86要舒服很多。
您是用ruby来做什么的?
0 请登录后投票
   发表时间: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问题,大着胆子说一句,有时候还真有些怀疑那谁的眼光和能力。
0 请登录后投票
   发表时间: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最大的问题是很多库都没跟上来。
0 请登录后投票
   发表时间:2009-04-22  
#encoding只对当前文件有效。

按理说跟所有外部模块和类传递的字符串在使用前都需要检查编码,而你可以这样做,写模块和类的人未必会这样做,所以我才说又麻烦又容易出错。

当然了,问题是可以解决的。首先自己小心一点,如果别人不小心,代码拿来改就是了。不当他是问题,当然就不是问题,1.8这么些年还不是照样用得好好的。
0 请登录后投票
   发表时间: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,感受一下……
0 请登录后投票
   发表时间:2009-04-22  
只要一沾带中文的 都那么麻烦
0 请登录后投票
论坛首页 编程语言技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics