Regex 在否定字符类中使用\s时混淆grep行为

Regex 在否定字符类中使用\s时混淆grep行为,regex,grep,Regex,Grep,我有一个正则表达式,它与“x”匹配,前提是它前面有一个非空格字符,而不是“和任意数量的空格字符: [^"\s]\s*x 这在JavaScript中可以正常工作: $ node > /[^"\s]\s*x/.test('x') false > /[^"\s]\s*x/.test(' x') false > /[^"\s]\s*x/.test('" x') false > /[^"\s]\s*x/.test(': x') true 不过,格雷普的行为有所不同: $ ech

我有一个正则表达式,它与“x”匹配,前提是它前面有一个非空格字符,而不是
和任意数量的空格字符:

[^"\s]\s*x
这在JavaScript中可以正常工作:

$ node
> /[^"\s]\s*x/.test('x')
false
> /[^"\s]\s*x/.test(' x')
false
> /[^"\s]\s*x/.test('" x')
false
> /[^"\s]\s*x/.test(': x')
true
不过,格雷普的行为有所不同:

$ echo 'x' | grep '[^"\s]\s*x'

$ echo ' x' | grep '[^"\s]\s*x'
 x

$ echo '" x' | grep '[^"\s]\s*x'
" x

$ echo ': x' | grep '[^"\s]\s*x'
: x
对这种行为有什么解释吗?我该如何重写grep的正则表达式,使其按预期的方式运行?

根据
[]
中的反斜杠,反斜杠是按字面理解的。因此,你的否定组不是“不是引号或空格字符”,而是“不是引号、反斜杠或s”


请改为尝试
[^”[:space:]

您可以指示grep与
-p
选项兼容:

$ echo 'x' | grep -P '[^"\s]\s*x'

$ echo ' x' | grep -P '[^"\s]\s*x'

$ echo '" x' | grep -P '[^"\s]\s*x'

$ echo ': x' | grep -P '[^"\s]\s*x'
: x


编辑:在Mac上删除了
-p
开关后不可能进行编辑,这是一个好消息,尽管默认的OS X安装不支持
-p
标志。奇怪的是,他们确实将
-p
作为有效选项列在自己的桌面上