Ruby中`\ w`与`[[:alpha:]]`之间Unicode行为的差异

时间:2018-05-15 17:57:23

标签: ruby regex unicode

(对于这个问题,请忽略\w的数字和下划线匹配,这与此处的讨论无关。)
根据{{​​3}},像\w这样的速记字符类和像[:alpha:]这样的POSIX类在Unicode方面都有类似的行为:它们具有简单的ascii行为,用于"不是Unicode Case& #34; (我认为这意味着字符串' s encoding不是Unicode),以及使用Unicode属性的不同行为" Unicode Case"。

从该文档中可以看出,其中一个使用Unicode属性,另一个也使用它们。但是,实际上它们似乎有所不同:POSIX类自动使用Unicode属性,而\w类型类必须使用?u显式标记以使用基于Unicode属性的匹配:

$ ruby -e 'print("~café.".encoding)'
UTF-8
$ ruby -e 'print(/[[:alpha:]]+/.match("~café."))'
café
$ ruby -e 'print(/\w+/.match("~café."))'
caf
$ ruby -e 'print(/(?u)\w+/.match("~café."))'
café
$ ruby -v
ruby 2.3.6p384 

这是一个错误,还是我对文档的解释错了? (?u究竟做了什么,有人可以链接到记录的位置吗?)

1 个答案:

答案 0 :(得分:4)

从2.0版开始,Ruby使用Onigmo,一个Oniguruma分支,支持在Perl 5.10中实现的更多功能。

如果您将链接的文档(Oniguruma)与Onigmo's doc进行比较,您可以看到\w描述之间的差异:

  • Oniguruma:
  

\ w字符

       Not Unicode:
         alphanumeric, "_" and multibyte char.

       Unicode: General_Category -- (Letter|Mark|Number|Connector_Punctuation)
  • Onigmo:
  

\ w字符

       Not Unicode:
         alphanumeric and "_".

       Unicode: General_Category -- (Letter|Mark|Number|Connector_Punctuation)

       It depends on ONIG_OPTION_ASCII_RANGE option that non-ASCII char includes or not.

正如你所看到的,没有更多的“和多字节字符。”没有意义(至少对我来说),这可能是一个错字。无论如何,这都是非常不清楚的。

u修饰符将速记字符类从“非Unicode”(默认)切换为“Unicode”。 这就是为什么当你尝试使用字符类caf匹配它时,只有café没有它和\w

另一方面,字符类[[:alpha:]]似乎已经默认扩展为unicode字符,因为它匹配没有u修饰符的“café”。可以在doc:

中找到解释的开始
  

它取决于ONIG_OPTION_ASCII_RANGE选项和       POSIX括号的ONIG_OPTION_POSIX_BRACKET_ALL_RANGE选项   是否匹配非ASCII字符。

但您可以使用(?a)修饰符强制它为ascii。