【问题标题】:Difference in Unicode behaviour between `\w` vs `[[:alpha:]]` in RubyRuby 中 `\w` 与 `[[:alpha:]]` 之间 Unicode 行为的差异
【发布时间】:2018-10-25 15:53:23
【问题描述】:

(对于这个问题,忽略\w的数字和下划线匹配,与这里的讨论无关。)
根据Oniguruma docs,像\w 这样的速记字符类和像[:alpha:] 这样的POSIX 类在Unicode 方面具有相似的行为:它们对于“非Unicode 大小写”具有简单的ascii 行为(我假设这意味着字符串的@ 987654327@ 不是 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 到底做了什么,有人可以链接到它的记录位置吗?)

【问题讨论】:

  • Ruby 的 RegExp 不一定与 Oniguruma 相同。 Ruby 文档确实说 \w 是 ASCII 而 [[:alpha]] 是 Unicode 感知的。不过,似乎两人都没有对(?u) 说任何话。我倾向于使用\w\s,......如果我特别想要ASCII-ish行为,否则\p{...}
  • u 实际上被描述为in the Ruby docs
  • @WiktorStribiżew 尾随 u(?u) 不同:/\w+/u.match("~café.") # => #<MatchData "caf">

标签: ruby regex unicode


【解决方案1】:

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

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

  • 鬼鬼祟:

\w 单词字符

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

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

\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.

如您所见,没有更多的这个 "and multibyte char." 没有意义(至少对我而言),这可能是一个错字。无论如何,这很不清楚。

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

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

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

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

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-10
  • 2021-10-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多