在正则表达式中组合负字符类

时间:2016-04-08 10:26:20

标签: ruby regex

给出这样的字符串:

a = 'Somewhere +in+ La-Mancha, in a |place| whose {name} I [do not care] to remember'

我想删除任何非单词和非空格字符。以下代码段按预期工作:

a.gsub(/[^\w\s]/,'')
# => "Somewhere in LaMancha in a place  whose name I do not care to remember"

但以下情况不起作用。

a.gsub(/[\W\S]/,'')
# => ""

理论上,两个正则表达式都是等价的,但它们不会以相同的方式工作。有谁知道原因?

是否可以组合负字符类?

2 个答案:

答案 0 :(得分:3)

  

理论上,两个正则表达式都是等价的

完全没有。

这是学校基本的逻辑。

  • not (A or B)(或等效地,(not A) and (not B)
  • (not A) or (not B)

是不同的。特别地,

  • [^\w\s]是:not(单词字符或空格字符)。
  • [\W\S]是:非单词字符或非空格字符。

他们是不同的。例如,非字的字符和空格匹配第二个正则表达式,但不匹配第一个正则字符。

  

是否可以组合负字符类?

是。字符类有交集运算符&&

/[\W&&\S]/

相当于[^\w\s]

答案 1 :(得分:3)

正面和负面角色类别中原子之间的关系是不同的。在正数中,原子是ORed(匹配此OR),在负字​​符类中,元素是AND(不匹配此AND)。

因此,[\W\S]匹配字母数字/下划线以外的字符,或者 - 如果找到 - 也匹配不等于空格的字符。 由于\W匹配空白而\S匹配任何非空格,因此[\W\S]匹配任何字符。这就是a.gsub(/[\W\S]/,'')返回空字符串的原因。

对于[^\w\s],它匹配任何不是字母数字/下划线且不是空格的字符。因此,它匹配任何非单词字符,没有空格字符([\W&&[^\s]]构造的同义词)。请参阅rubular demo

还有一个插图

\W是一个通用的速记字符类,匹配所有非单词(或匹配除“单词”以外的任何字符)字符。现在,除了; 之外,我们希望匹配所有非字字符。分号是非单词字符。我们该怎么办?我们可以使用具有相反类\w - [^\w]的否定字符类 - 并将;添加到其中 - > [^\w;]。此[^\w;]将匹配任何非字和非;字符。