【问题标题】:why \s+ do not match the space in macro with grep?为什么 \s+ 不将宏中的空格与 grep 匹配?
【发布时间】:2017-08-30 16:11:14
【问题描述】:

我想搜索ZEND_BEGIN_ARG_INFO_EX的宏定义,

所以我运行命令

 grep   "define\s+ZEND_BEGIN_ARG_INFO_EX" -r  ./ 

但它什么也没找到。

所以,我试试

grep   "define\s*ZEND_BEGIN_ARG_INFO_EX" -r  ./

成功返回ZEND_BEGIN_ARG_INFO_EX的定义,返回

./Zend/zend_API.h:#define ZEND_BEGIN_ARG_INFO_EX  ....

我的问题:

为什么\s+与宏中的空格不匹配?

我认为它应该至少匹配一个空格。

【问题讨论】:

  • \s 是 ERE 语法。
  • @Cyrus,不是 ERE,而是 PCRE。

标签: regex shell grep


【解决方案1】:

这里有两个问题:

  • \s 是 PCRE 语法。 grep 支持 BRE(默认)或 ERE(当被称为 egrep 或传递 -E 参数时),但不支持 PCRE 缺少非标准扩展。请改用[[:space:]]

  • + 是 ERE 语法,而默认情况下 grep 使用 BRE。将-E 传递给grep,或者将其作为egrep 调用,以启用ERE。

因此:

grep -Ere "define[[:space:]]+ZEND_BEGIN_ARG_INFO_EX" ./

【讨论】:

  • GNU 对grep 的实现支持\s 作为扩展。这是 POSIX 允许的。
  • @hvd,允许但不是必需的,因此依赖它绝不是安全的。你确定这是 grep 的一部分,而不是 glibc 的一部分?如果是后者,则即使在 GNU grep 上也不能可靠地使用,具体取决于当前平台。 (它当然是 bash 的 [[ $var =~ $regex ]] 内置的 libc 提供的)。
  • 是的,但是因为 OP 的实现确实接受它,所以这无法回答这个问题。 OP 遇到的问题是由于 + 匹配 BRE 中的文字加号。至于您编辑的评论,不确定它是 grep 还是 glibc 的一部分。
  • 啊;我在那里略过这个问题有点太快了。已修改。
【解决方案2】:

Linux 自带的标准 grep 不接受+,只接受*。你可以这样说:

grep "define\s\s*ZEND_BEGIN_ARG_INFO_EX" -r ./ 

或者这个

grep -E "define\s+ZEND_BEGIN_ARG_INFO_EX" -r ./ 

【讨论】:

  • grep -E 肯定是POSIX standard for grep 的一部分。也许应该添加“默认”一词?并且忽略标准也不保证\s 是一个相当大的疏忽。
  • 已修改。顺便说一句,现在哪个版本的 grep 不支持 \s
  • 首先想到的是busybox。也就是说,直到 2010 年,\s 甚至连 GNU grep 都没有记录在案。
  • (当然,busybox 使用平台的正则表达式引擎,所以它支持什么语法取决于它编译的 libc)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-12-04
  • 2011-09-12
  • 1970-01-01
  • 2013-08-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多