gpt4 book ai didi

ruby - 正则表达式 "punct"字符类根据 Ruby 版本匹配不同的字符

转载 作者:数据小太阳 更新时间:2023-10-29 07:58:43 24 4
gpt4 key购买 nike

Ruby 的标点字符 字符类,即[:punct:]\p{Punct}\p {P} 似乎根据我使用的 Ruby 版本匹配不同的字符。

这是一个小例子:(很抱歉弄乱了 SO 的语法高亮显示)

# punct.rb
chars = <<-EOD.split
! " # $ % & ' ( ) * + , - . / : ; < = > ? @ [ ] ^ _ ` { | } ~
EOD

matched, not_matched = chars.partition { |c| c =~ /[[:punct:]]/ }

puts " matched: #{matched.join}"
puts "not matched: #{not_matched.join}"

使用 Ruby 1.9.3 和 Ruby 2.4.0 我得到:

    matched: !"#$%&'()*+,-./:;<=>?@[]^_`{|}~
not matched:

但是中间的各种 Ruby 版本(2.0.x、2.1.x、2.2.x、2.3.x)给我:

    matched: !"#%&'()*,-./:;?@[]_{}
not matched: $+<=>^`|~

为什么会这样,什么是正确的行为?更重要的是:如何在 Ruby 版本之间实现一致的结果?

尝试更改我的语言环境无济于事(如 Why does Ruby /[[:punct:]]/ miss some punctuation characters? 所建议)。

最佳答案

Ruby 1.9.3 使用 US_ASCII 作为其默认编码,可以正确匹配所有标点符号。 Ruby 2.0 将其默认编码切换为 UTF-8,引入了您发现的错误,导致标点符号匹配不当。 Ruby 2.4 修补了这个错误。

正确的行为是匹配所有标点符号,就像 ruby​​ 1.9.3 和 2.4 所做的那样。这与标点符号的 POSIX 正则表达式定义一致。

使您的代码保持一致的一种选择是将所有字符串编码为 US_ASCII 或没有 UTF-8 错误的替代方案:

匹配,不匹配 = chars.partition { |c| c.encode(编码::US_ASCII) =~/[[:punct:]]/}

但这可能并不理想,因为它会强制您对字符串使用限制性编码。

另一种选择是手动定义标点符号:

/[!"\#$%&'()*+,\-./:;<=>?@\[\\\]^_`{|}~]/

它有点不优雅,但您可以将它放入一个变量中并以这种方式将其添加到正则表达式中:

punctuation = "[!\"\#$%&'()*+,\-./:;<=>?@\[\\\]^_`{|}~]"
my_regex = /#{punctuation}/

关于ruby - 正则表达式 "punct"字符类根据 Ruby 版本匹配不同的字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42070203/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com