问题 如何在ruby中使用正则表达式的utf8


在RoR中,如何使用utf8代码验证中文或日语单词的发布表单。

在GBK代码中,它使用[\ u4e00- \ u9fa5] +来验证中文单词。 在Php中,它使用/ ^ [\ x {4e00} - \ x {9}} + $ / u来表示utf-8页面。


3799
2017-11-02 12:06


起源



答案:


Ruby 1.8对UTF-8字符串的支持很差。您需要在正则表达式中单独写入字节,而不是完整代码:

>> "acentuação".scan(/\xC3\xA7/)
=> ["ç"]    

要匹配您指定的范围,表达式将变得有点复杂:

/([\x4E-\x9E][\x00-\xFF])|(\x9F[\x00-\xA5])/  # (untested)

这将在Ruby 1.9中得到改进但是。

编辑: 如注释中所述,unicode字符\ u4E00- \ u9FA5仅映射到UTF16-BE编码中的上述表达式。 UTF8编码可能不同。因此,您需要仔细分析映射,看看是否可以为Ruby 1.8提供字节匹配表达式。


10
2017-11-02 12:36



当您使用8位正则表达式引擎(例如Ruby 1.8中的那个)处理UTF-8文本时,标记为“未经测试”的正则表达式肯定不等同于[\ u4e00- \ u9FA5]。只有在使用8位正则表达式引擎处理UTF-16BE文本时,您的正则表达式才有效。 - Jan Goyvaerts


答案:


Ruby 1.8对UTF-8字符串的支持很差。您需要在正则表达式中单独写入字节,而不是完整代码:

>> "acentuação".scan(/\xC3\xA7/)
=> ["ç"]    

要匹配您指定的范围,表达式将变得有点复杂:

/([\x4E-\x9E][\x00-\xFF])|(\x9F[\x00-\xA5])/  # (untested)

这将在Ruby 1.9中得到改进但是。

编辑: 如注释中所述,unicode字符\ u4E00- \ u9FA5仅映射到UTF16-BE编码中的上述表达式。 UTF8编码可能不同。因此,您需要仔细分析映射,看看是否可以为Ruby 1.8提供字节匹配表达式。


10
2017-11-02 12:36



当您使用8位正则表达式引擎(例如Ruby 1.8中的那个)处理UTF-8文本时,标记为“未经测试”的正则表达式肯定不等同于[\ u4e00- \ u9FA5]。只有在使用8位正则表达式引擎处理UTF-16BE文本时,您的正则表达式才有效。 - Jan Goyvaerts


这就是我所做的:

%r{^[#{"\344\270\200"}-#{"\351\277\277"}]+$}

这基本上是一个正则表达式,其八进制值表示U + 4E00和U + 9FFF之间的范围,这是最常见的中文和日文字符。


3
2017-12-28 19:06





Oniguruma regexp引擎对Unicode有适当的支持。 Ruby 1.9默认使用Oniguruma。可以重新编译Ruby 1.8以使用它。

使用Oniguruma,您可以使用与PHP完全相同的正则表达式,包括/ u修饰符,以强制Ruby将字符串视为UTF-8。


2
2017-11-03 00:20





activeSupport有一个UTF-8处理程序

http://api.rubyonrails.org/classes/ActiveSupport/Multibyte/Handlers/UTF8Handler.html


否则,请查看ruby 1.9,Regexp对象的编码方法


1
2017-11-02 12:57



这是一个破碎的链接...... - nivcaner
那是因为自ActiveSupport 2.1以来它已被弃用: apidock.com/rails/ActiveSupport/Multibyte/Handlers - Leonid Shevtsov