【问题标题】:Why does Ruby /[[:punct:]]/ miss some punctuation characters?为什么 Ruby /[[:punct:]]/ 会漏掉一些标点符号?
【发布时间】:2019-07-25 06:03:57
【问题描述】:

Ruby /[[:punct:]]/ 应该匹配所有“标点符号”。根据Wikipedia,这意味着/[\]\[!"#$%&'()*+,./:;<=>?@\^_`{|}~-]/ 符合POSIX 标准。

匹配:-[]\;',./!@#%&*()_{}::"?

但是,它确实匹配:=`~$^+|<>(至少在 ruby​​ 1.9.3p194 中)。

什么给了?

【问题讨论】:

  • 我的 glibc 文档说 [[:punct:]] 应该匹配 wctype(3) 称为标点符号的任何内容; ispunct(3) 页面显示 checks for any printable character which is not a space or an alphanumeric character.。这似乎很明确。
  • Ruby's RE engine is special, though -- 有关于 punct 类的 Unicode 大小写和非 Unicode 大小写的文档。我仍然不确定这具体意味着什么,但我希望这会有所帮助。

标签: ruby regex posix


【解决方案1】:

标点字符类由语言环境定义。开放组LC_TYPE definition for punct 说:

定义要分类为标点字符的字符。在 POSIX 语言环境中,<space> 或 alpha、digit 或 cntrl 类中的任何字符都不应包含在内。在语言环境定义文件中,不得为关键字upper、lower、alpha、digit、cntrl、xdigit或as指定任何字符。

基本上,它定义了如何通过排除其他字符类来定义 punct,但它实际上并不直接定义标点符号——这是语言环境的工作。

我找不到每个语言环境中内容的规范参考。也许别人知道。同时,你可以找到一个匹配你想要的punct字符类的LC_TYPE,或者直接指定类。

【讨论】:

  • FWIW,我的语言环境是 Rails 的默认 en(非 Rails 普通 irb 也是如此,我的操作系统是 en_US)。关于如何解决这个问题的任何建议(不仅仅是明确的)?我希望没有更多的随机陷阱……
【解决方案2】:

大于符号在"Symbol, Math" category 中,而不是标点符号类别中。如果您将正则表达式的编码强制为 UTF-8,您可以看到这一点(它默认为源编码,并且可能您的源是 UTF-8 编码的,而我的默认源是其他的):

2.1.2 :004 > /[[:punct:]]/u =~ '<'
 => nil 
2.1.2 :005 > /[[:punct:]]/ =~ '<'
 => 0 

如果您将正则表达式强制为 ASCII 编码(/n - 更多选项 here),您会看到它在 punct 中将“

2.1.2 :009 > /[[:punct:]]/n =~ '<'
 => 0 

更好的解决方案是在您的正则表达式中使用“符号”类别而不是“punct”类别,后者与 UTF-8 编码中的“

2.1.2 :012 > /\p{S}/u =~ '<'
 => 0 

here 的类别列表更长。

【讨论】:

  • 符号不包括实际的标点符号,例如,.:"。两者的组合涵盖了 ASCII 范围内的所有“标点”字符(由 POSIX 定义)。但是,如果我们使用符号和标点符号通用类别的组合,也会包括货币符号、版权符号、箭头和各种其他符号。
猜你喜欢
  • 2015-07-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-27
  • 2014-06-12
  • 1970-01-01
  • 2011-01-19
  • 2013-10-12
相关资源
最近更新 更多