快速业务通道

JavaEye3.0开发手记之二 - rails的UTF-8支持造成的正则表达式问题 - 编程入门网

作者 佚名技术 来源 NET编程 浏览 发布时间 2012-06-14
a-z0-9_]+/  => nil  irb(main):004:0> name.match /\w+/  => nil

JavaEye3.0开发手记之二 - rails的UTF-8支持造成的正则表达式问题(3)

时间:2011-11-20 javaeye robbin

请注意标记为红色的行,在ruby的内存中,中文字符串的编码使用的是unicode格式,中文字符串不能 够匹配到/[\w]+/上面去,而/[A-Za-z0-9_]+/与/\w+/是同义词。

好了,现在启动rails的环境:

引用

$ ./script/console 
Loading development environment. 
>> load "char.rb" 
=> [] 
>> name 
=> "鑼冨嚡" 
>> name.match /[A-Za-z0-9_]+/ 
=> nil 
>> name.match /\w+/ 
=> #

哈哈,水落石出了!!由于rails的ActiveSupport的引入,在ruby的内存当中,字符串被转换为UTF-8 格式了(显示乱码是因为我的Windows操作系统是GBK编码),而中文字符串居然可以匹配/\w+/了!

我们可以看到,由于rails在内存当中以UTF-8格式操作中文字符串,而不是ruby默认的unicode格式, 这就导致了正则表达式的歧义:/[A-Za-z0-9_]+/不能匹配中文,但是/\w+/可以匹配中文,但实际上在 ruby当中,这两个正则表达式本应该是同义词。

明白了问题的根源,就清楚了如何去解决auto_link的bug,修改正则表达式和相关方法,将\w替换为 A-Za-z0-9,并将其放入你的rails项目的application_helper.rb当中,这样就可以在项目启动以后覆盖 rails系统类库的定义:

Ruby代码

 AUTO_LINK_RE = %r{ 
            (             # leading text 
             <\w+.*?>|        # leading HTML tag, or 
             [^=!:''"/]|        # leading punctuation, or 
             ^            # beginning of line 
            ) 
            ( 
             (?:https?://)|      # protocol spec, or 
             (?:www\.)        # www.* 
            ) 
            ( 
             [-0-9A-Za-z_]+      # subdomain or domain 
             (?:\.[-0-9A-Za-z_]+)*  # remaining subdomains or domain 
             (?::\d+)?        # port 
             (?:/(?:(?:[~0-9A-Za-z_\+%-]|(?:[,.;:][^\s$]))+)?)* # path 
             (?:\?[0-9A-Za-z_\+%&=.;-]+)?   # query string 
             (?:\#[0-9A-Za-z_\-]*)?  # trailing anchor 
            ) 
 }x unless const_defined?(:AUTO_LINK_RE) 
  
 def auto_link_urls(text, href_options = {}) 
  extra_options = tag_options(href_options.stringify_keys) || "" 
  text.gsub(AUTO_LINK_RE) do 
   all, a, b, c = contentamp;, $1, $2, $3 
   if a =~ /<a\s/i # don''t replace URL''s that are already linked 
    all 
   else 
    text = b + c 
    text = yield(text) if block_given? 
    %(#{a}<a href="#{b=="www."?"http://www.":b}#{c}"#{extra_options}>#{text}

</a>) 
   end 
  end 
 end

OK,搞定了,这下auto_link可以正确截断中文了。

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号