[[:punct:]]在irb和rails test

时间:2017-05-22 14:46:02

标签: ruby regex unit-testing ruby-on-rails-4

[[:punct:]]在通过rails模型测试调用时不匹配任何标点符号。使用以下代码

test "punctuation matched by [[:punct:]]" do
  punct_match = /\A[[:punct:]]+\Z/.match('[\]\[!"#$%&\'()*+,./:;<=>?@\^_`{|}~-]')

  puts punct_match
  puts punct_match.class
end

这会输出一个不可打印的字符和NilClass。

但是,如果我执行相同的声明

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

正确匹配并输出

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

我错过了什么?

Ruby版本=&gt; 2.2.4, Rails版本=&gt; 4.2.6

1 个答案:

答案 0 :(得分:2)

/[[:punct:]]/的行为在ruby版本2.4.0中稍有改变。

在红宝石问题中引发了

This bug,这些问题链接回Onigmo中的this (much older)问题 - 自Ruby 2.0+以来使用的正则表达式引擎。

简短的回答是,这些字符在ruby版本/[[:punct:]]/中与<2.4.0不匹配,现在匹配:

$+<=>^`|~

你必须在比这个rails应用程序更新的ruby版本中运行irb,这就是它匹配的原因。

另外,您应该稍微改变您的代码:

/\A[[:punct:]]+\z/.match('[]!"#$%&\'()*+,./:;<=>?@^_`{|}~-]')
  • 使用\z,而不是\Z。有一个slight difference\Z也会匹配字符串末尾的新行。
  • 字符串中有不必要的反斜杠,例如'\^'
  • 您重复了[个字符:'[\]\['