我如何匹配`:punct:`除了某些字符?

not*_*123 2 ruby regex

我想匹配除单引号之外的所有标点符号.

我尝试了以下内容.

  • /[^'[:punct:]] 否定所有标点符号.
  • [(^')[:punct:]]似乎完全无视^'.

如果没有,我想我总是可以写出完整的:punct:除了'.

rev*_*evo 6

这可以使用负前瞻:

(?!')[[:punct:]]
Run Code Online (Sandbox Code Playgroud)


Ama*_*dan 5

来自Ruby文档:

字符类可能包含另一个字符类.这本身并没有用,因为它[a-z[0-9]]描述了相同的集合[a-z0-9].但是,字符类还支持&&在其参数上执行set intersection 的运算符.

所以,"标点符号而非撇号"是:

[[:punct:]&&[^']]
Run Code Online (Sandbox Code Playgroud)

编辑:根据revo问题评论的要求,在我的机器上,这个基准测试预测为慢了约10%,并且看起来慢了约20%:

require 'benchmark'

N = 1_000_000
STR = "Mr. O'Brien! Please don't go, Mr. O'Brien!"

def test(bm, re)
  N.times {
    STR.scan(re).size
  }
end

Benchmark.bm do |bm|
  bm.report("intersection") { test(bm, /[[:punct:]&&[^']]/) }
  bm.report("lookahead") { test(bm, /(?!')[[:punct:]]/) }
  bm.report("lookbehind") { test(bm, /[[:punct:]](?<!')/) }
end
Run Code Online (Sandbox Code Playgroud)

  • @revo:不完全 - 我所指的版本是1.9.2.所以这是Ruby 1.9.3+.但是如果我为每个答案选择研究版本历史,我都会被诅咒.如果有人告诉我一个_currently supported_版本无法处理它,我肯定会编辑它,因为它是相关的信息.EOL的版本?不值得. (3认同)