ruby - 使用\d 扫描字符串中的 Unicode 数字

标签 ruby regex unicode character-properties

根据 the Oniguruma documentation\d 字符类型匹配:

decimal digit char
Unicode: General_Category -- Decimal_Number

但是,在包含所有 Decimal_Number 字符的字符串中扫描 \d 会导致仅匹配拉丁文 0-9 数字:

#encoding: utf-8
require 'open-uri'
html = open("http://www.fileformat.info/info/unicode/category/Nd/list.htm").read
digits = html.scan(/U\+([\da-f]{4})/i).flatten.map{ |s| s.to_i(16) }.pack('U*')

puts digits.encoding, digits
#=> UTF-8
#=> 0123456789٠١٢٣٤٥٦٧٨٩۰۱۲۳۴۵۶۷۸۹߀߁߂߃߄߅߆߇߈߉०१२३४५६७८९০১২৩৪৫৬৭৮৯੦੧੨…

p RUBY_DESCRIPTION, digits.scan(/\d/)
#=> "ruby 1.9.2p180 (2011-02-18) [i386-mingw32]"
#=> ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]

我是不是误读了文档?为什么 \d 不匹配其他 Unicode 数字,和/或有什么办法可以做到这一点?

最佳答案

Brian Candler on ruby-talk 记录:

  • \w 仅匹配 ASCII 字母和数字,而 [[:alpha:]] 匹配完整的 Unicode 字母集。
  • \d 仅匹配 ASCII 数字,而 [[:digit:]] 匹配完整的 Unicode 数字集。

因此行为是“一致的”,我们有一个针对 Unicode 数字的简单解决方法。阅读 the same Oniguruma doc 中的 \w我们看到文字:

\w  word character  
    Not Unicode: alphanumeric, "_" and multibyte char.  
    Unicode: General_Category -- (Letter|Mark|Number|Connector_Punctuation)

根据 Ruby 的实际行为和上面的“非 Unicode”文本,文档似乎描述了两种模式——Unicode 模式和非 Unicode 模式——并且 Ruby 在非 Unicode 模式下运行.

这可以解释为什么 \d 不匹配完整的 Unicode 集:尽管 Oniguruma 文档未能准确描述在非 Unicode 模式下匹配的内容,但我们现在知道行为记录为“Unicode"是不可预料的。

p "abç".scan(/\w/), "abç".scan(/[[:alpha:]]/)
#=> ["a", "b"]
#=> ["a", "b", "\u00E7"]

留给读者作为练习来发现如何(如果有的话)在 Ruby 正则表达式中启用 Unicode 模式,作为 /u 标志(例如 /\w/u ) 不这样做。 (也许 Ruby 必须用 Oniguruma 的特殊标志重新编译。)

更新:看来我链接到的 Oniguruma 文档对于 Ruby 1.9 不准确。参见 this ticket discussion ,包括这些帖子:

[Yui NARUSE] "RE.txt is for original Oniguruma, not for Ruby 1.9's regexp. We may need our own document."
[Matz] "Our Oniguruma is forked one. The original Oniguruma found in geocities.jp has not been changed."

更好的引用:这是关于 Ruby 1.9 的正则表达式语法的官方文档:
https://github.com/ruby/ruby/blob/trunk/doc/re.rdoc

关于ruby - 使用\d 扫描字符串中的 Unicode 数字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6998713/

相关文章:

ruby - 安装 Ruby 后 MAC OS X 上的事件开发者路径无效

c# - 正则表达式(匹配词+一些数字)C#

regex - 带有可选的 2 个十进制数字的 6 位数字的正则表达式

postgresql - Clojure jdbc postgres : Why do the results from my query return unicode characters in table names as �?

ruby - 无需循环即可将列表解析为多维数组

ruby - 都做吗?和任何?保证短路评估?

regex - TypeScript 字符串替换为正则表达式、组和部分字符串

css - 浏览器支持不同语言的 UTF 8 Unicode 字体

string - 如何在 Racket 中对 unicode 字符串进行 uri 编码

ruby-on-rails - 没有要加载的文件 -- nokogiri