`
wqy159
  • 浏览: 56051 次
  • 性别: Icon_minigender_2
  • 来自: 北京
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

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

阅读更多

网站:JavaEye 作者:robbin 发表时间: 2007-08-22 13:18 此文章来自于 http://www.iteye.com
声明:本文系JavaEye网站原创文章,未经JavaEye网站或者作者本人书面许可,任何其他网站严禁擅自发表本文,否则必将追究法律责任!
原文链接: http://www.iteye.com/topic/115235

rails的ActionView::Helpers::TextHepler模块提供了很多实用的方法,这些方法对于论坛类应用非常有用,例如auto_link这个方法可以自动检测传入字符串当中的URL,并将其自动转换为HTML超链接格式,这对于显示帖子的内容来说很不错。

但是在开发JavaEye3.0的时候,却发现auto_link有bug,一旦帖子当中的URL后面紧跟中文的话,auto_link就会把URL后面所有的中文当做URL的一部分进行格式化,直到碰到空格为止,例如:

引用
http://www.iteye.com网站很不错

就会被格式化为:

引用

看来得到rails的源代码里找答案了。

打开netbeans,敲快捷键Ctrl+O,在弹出窗口输入:texthelper,回车,netbeans已经帮我打开了text_helper.rb源代码,通过Navigator窗口,很方便的定位到auto_link方法,仔细看一下,原来主要是这个正则表达式在起作用:

[code="ruby"]
AUTO_LINK_RE = %r{
( # leading text
<\w+.*?>| # leading HTML tag, or
[^=!:'"/]| # leading punctuation, or
^ # beginning of line
)
(
(?:https?://)| # protocol spec, or
(?:www\.) # www.*
)
(
[-\w]+ # subdomain or domain
(?:\.[-\w]+)* # remaining subdomains or domain
(?::\d+)? # port
(?:/(?:(?:[~\w\+%-]|(?:[,.;:][^\s$]))+)?)* # path
(?:\?[\w\+%&=.;-]+)? # query string
(?:\#[\w\-]*)? # trailing anchor
)
([[:punct:]]|\s|<|$) # trailing text
}x unless const_defined?(:AUTO_LINK_RE)
[/code]

但这个正则表达式上看下看,左看右看都没有啥问题阿。于是把这个正则表达式拷贝出来,放在一个ruby文件里面test.rb,一点点单独调试,但怎么调试都正常,即使把上面那个URL放进去,也可以正常截断中文。

难道是因为rails做了手脚?为了验证这一点,在test.rb前面加上如下内容:

[code="ruby"]
ENV["RAILS_ENV"] = "development"
require File.expand_path(File.dirname(__FILE__) + "/../config/environment")
[/code]

再运行test.rb,果然!中文又被包括进去了,看来就是rails做了手脚。

再回过头仔细看这个正则表达式,只有[\w]和字符串处理有关系,为了验证这一点,我们做如下试验:

创建一个char.rb文件,内容如下:

[code="ruby"]
def name
return "范凯"
end[/code]

请注意!该文件保存格式请必须使用UTF-8!!
然后打开irb,进行如下交互:

引用
irb(main):001:0> load "char.rb"
=> true
irb(main):002:0> name
=> "\350\214\203\345\207\257"

irb(main):003:0> name.match /[A-Za-z0-9_]+/
=> nil
irb(main):004:0> name.match /\w+/
=> nil

请注意标记为红色的行,在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系统类库的定义:

[code="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 = $&, $1, $2, $3
if a =~ /#{text})
end
end
end
[/code]

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




《 JavaEye3.0开发手记之二 - rails的UTF-8支持造成的正则表达式问题 》 的评论也很精彩,欢迎您也添加评论。查看详细 >>

推荐相关文章:
  JavaEye3.0开发手记之一 - 我的开发环境




JavaEye推荐
上海乐福狗信息技术有限公司:诚聘技术经理和开发工程师
免费下载IBM社区版软件--它基于开放的标准,支持广泛的开发类型,让您的开发高效自主!
京沪穗蓉四地免费注册,SOA技术高手汇聚交锋.
上海:优秀公司德比:高薪诚聘 资深Java工程师
广州:优易公司:诚聘Java工程师,开发经理
上海:尤恩斯国际集团:诚聘开发工程师
北京:优秀公司NHNChina招聘:WEB开发,系统管理,JAVA开发, DBA


分享到:
评论

相关推荐

    JavaEye3.0开发手记

    ### JavaEye3.0开发手记之开发环境搭建详解 #### 一、开发环境搭建概述 随着JavaEye3.0开发计划的启动,本篇文章将详细介绍如何为该项目搭建高效的开发环境。开发过程中不仅需要考虑软件的选择,还需要针对操作...

    QRe 正则表达式测试工具

    用法java -jar QRe.jar 运行环境:...支持匹配处高亮显示 2.支持group 3.支持多次匹配 &lt;br&gt;不废话了,请看截图: http://www.javaeye.com/topics/download/0238851c-019f-358f-a72e-ce54e0bede90&lt;br&gt;

    一个java正则表达式工具类源代码.zip(内含Regexp.java文件)

    * Summary of regular-expression constructs 正则表达式结构简介: * Construct Matches * Characters 字符: * x The character x x 字符 x * \\ The ...

    JavaEye论坛热点_-_2008年11月_-_总第6期

    - Sun的Regexpr实现可能成为讨论的焦点,因为正则表达式在文本处理和数据验证中广泛使用,其效率和兼容性是开发者关心的问题。 12. **ORM框架的探讨** - ORM(对象关系映射)工具如Hibernate和MyBatis,简化了...

    JavaEye2.0_on_rails

    ### JavaEye2.0_on_rails:敏捷Web开发实践与Ruby on Rails的应用 #### 敏捷软件开发方法 - **背景**:传统软件工程方法在实际应用中面临着项目延期、成本超支以及软件质量不高的问题。为了克服这些挑战,业界提出...

    ruby study

    ### Ruby中的正则表达式详解 #### 一、引言 在编程语言Ruby中,正则表达式(Regular Expression)是一种强大的文本处理工具,用于模式匹配、搜索与替换字符串等功能。Ruby采用`//`作为正则表达式的边界标记,使得...

    基于JavaEye-API实现的Gerry-聊天Dos版v1.0-lib库

    NULL 博文链接:https://ago520.iteye.com/blog/814571

    基于JavaEye-API实现的Gerry-聊天QQ版v1.0 (全)

    NULL 博文链接:https://ago520.iteye.com/blog/754087

    JavaEye新闻月刊_-_2009年3月_-_总第13期

    JavaEye新闻月刊2009年3月第13期内容涉及了当时软件开发领域内的一系列重要话题,包括IBM拟收购Sun Microsystems公司的新闻报道、Java社区对此的看法以及各种编程语言、开发工具和技术的新动态。 首先,新闻月刊...

    关于用oracle的dbms_xmldom导出xml文档编码格式UTF-8的问题总结

    ### 关于用Oracle的DBMS_XMLDOM导出XML文档编码格式UTF-8的问题总结 在处理Oracle数据库中使用DBMS_XMLDOM模块创建并导出XML文档时,经常会遇到有关文档编码格式的问题,尤其是如何确保导出的XML文档采用UTF-8编码...

    Java学习网站---API手册下载---开发工具---项目源码---学习资料汇总

    Java是世界上最流行的编程语言之一,尤其在企业级应用开发领域占据主导地位。为了深入学习Java,了解并掌握其API(应用程序接口)以及使用高效的开发工具是至关重要的。下面,我们将详细探讨Java学习网站、API手册、...

    Ruby on Rails

    在Linux平台上安装和配置Ruby on Rails详解 - rails - Ruby - JavaEye论坛.htm

    JavaEye论坛热点推荐_-_2009年09月_-_总第16期.pdf

    【JavaEye论坛热点推荐 - 2009年09月 - 总第16期】 这期JavaEye论坛的热点推荐涵盖了多个Java相关的技术话题,包括JDK7的新特性、HTTP缓存、Android开发、Java编程面试问题、Hibernate缓存、网页数据存储设计、热...

    HTML压缩代码 VB6源码

    VB6不内置支持正则表达式,但可以通过引入Microsoft的VBA RegEx库来实现。 3. **模块(Module)**:在VB6项目中,`Module1.bas`可能包含实现HTML压缩逻辑的函数或子过程。模块可以存放全局变量、函数和过程,它们在...

    javaeye热点阅读

    19. Ruby on Rails:Ruby on Rails是一个流行的Web开发框架,文中探讨了其在企业开发、嵌入式开发中的应用,以及工作流实现。 20. AJAX技术:包括ExtJS基础教程和jQuery图片循环效果,展示了AJAX如何提升用户体验。...

Global site tag (gtag.js) - Google Analytics