与gsub的怪异

时间:2012-04-27 15:12:42

标签: ruby regex rspec ruby-1.9 gsub

我试图使用gsub删除rails应用中字符串中的非单词字符。我使用了以下代码:

somestring.gsub(/[\W]/i, '')  #=> ""

但实际上它不正确,它也会删除字母k。正确的应该是:

somestring.gsub(/\W/i, '')  #=> "kkk"

但我的问题是使用rspec包含上述代码的rails控制器的单元测试不起作用,单元测试实际上通过了。所以我在rspec中创建了一个非常极端的测试用例

it "test this gsub" do
  'kkk'.gsub(/[\W]/i, '').should == 'kkk'
end

上面的测试用例应该会失败,但它确实会通过。这里有什么问题?为什么测试通过?

1 个答案:

答案 0 :(得分:5)

Ruby 1.9切换到另一个正则表达式引擎(Oniguruma),它解释了行为的变化。这似乎是一个错误。

对于您的示例,您可以通过不指定不区分大小写的匹配来解决此问题:

irb(main):001:0> 'kkk'.gsub(/[\W]/i, '')
=> ""
irb(main):002:0> 'kkk'.gsub(/[\W]/, '')
=> "kkk"
irb(main):004:0> 'kkk'.gsub(/\W/i, '')
=> "kkk"
irb(main):003:0> 'kkk'.gsub(/\W/, '')
=> "kkk"

更新:看起来删除字符组是另一种方法。可能是这样的否定匹配在字符组中不一定有效吗?