首页 > 解决方案 > 为什么某些 Unicode 组合标记(如 \u0BCD)与 Ruby 中的 [:alpha:] 不匹配?

问题描述

我正在尝试在泰米尔语 Unicode 代码点上使用 Ruby Regexp。两者\u0BC0\u0BCD都在字符类别中组合元音标记Mark, Nonspacing [Mn],根据我的理解,这应该与[:alpha:]该类匹配。但\u0BCD似乎与班级不符。

irb(main):002:0> "\u0BAE\u0BC0\u0BA9\u0BCD\u0BA9".scan(/[[:alpha:]]+/).each { |s| puts s.dump }
"\u0BAE\u0BC0\u0BA9"
"\u0BA9"
=> ["மீன", "ன"]
irb(main):003:0> 

我在 OS X 10.15.2 上使用 Ruby 2.6.5p114。会发生什么?

标签: regexrubyunicode

解决方案


有问题的两个字符是(我用粗体标记了一些有趣的东西):

该类Ruby 文档Regexp没有明确说明[[:alpha:]]匹配的内容,但确实说POSIX 括号表达式匹配非 ASCII 字符,并[[:digit:]]举例说明它匹配具有 Unicode 属性Nd (Decimal Number)的任何内容。

Regexp 虽然没有明确记录,但将POSIX 括号表达式 等同于[[:alpha:]]Unicode 属性Alphabetic是有意义的,这意味着 U+0BC0 匹配而 U+0BCD 不匹配。

另一方面,Onigmo 的文档RegexpYARV 中使用的引擎,并在所有其他实现中镜像)确实明确指定了[[:alpha:]]. 事实上,它在两个不同的地方指定了它,它们相互矛盾:

因此,似乎正在发生的事情是,Unicode 联盟不认为U+0BCD 是字母,因此,Onigmo 和 Ruby 不将其归类为[[:alpha:]]. 在这种情况下,Onigmo 文档是不正确的,而 Ruby 文档是不精确的。


推荐阅读