ch4*_*h2o 6 grep regular-expression
为什么grep
macOS上的 BSD在这里只产生第一个词:
$ echo "once upon a time" | grep -o "[a-z]*"
once
Run Code Online (Sandbox Code Playgroud)
但这里所有的话:
$ echo "once upon a time" | grep -o "[a-z][a-z]*"
once
upon
a
time
Run Code Online (Sandbox Code Playgroud)
或者,使用扩展的正则表达式:
$ echo "once upon a time" | grep -E -o "[a-z]*"
once
$ echo "once upon a time" | grep -E -o "[a-z]+"
once
upon
a
time
Run Code Online (Sandbox Code Playgroud)
GNUgrep
将为[a-z]+
(or [a-z][a-z]*
) 和生成相同的输出[a-z]*
:
$ echo "once upon a time" | ggrep -E -o "[a-z]*"
once
upon
a
time
$ echo "once upon a time" | ggrep -E -o "[a-z]+"
once
upon
a
time
Run Code Online (Sandbox Code Playgroud)
收集评论部分的想法,这似乎归结为不同的grep
实现决定如何处理空匹配以及[a-z]*
空字符串上的表达式匹配。
该-o
选项不是由 POSIX 定义的,因此实现方式如何处理它留给开发人员。
GNUgrep
显然会丢弃空匹配,例如once
使用 时后面的空字符串的匹配[a-z]*
,并继续从下一个字符开始处理输入。
BSDgrep
似乎正在打空火柴,并决定,无论出于何种原因,这就足够了,并就此停止。
St\xc3\xa9phane 提到,ast-open
的版本实际上在aftergrep
的空匹配处进入无限循环,并且不会超过字符串中的该点。[a-z]*
once
OpenBSDgrep
似乎与 macOS 和 FreeBSD 不同grep
,因为添加-w
标志(要求匹配由单词边界分隔)使得[a-z]*
单独返回每个单词。
ilkkachu 观察到,-o
在某种意义上允许匹配空字符串的模式是令人困惑的(或者可能至少是模棱两可的)。是否应该打印所有空匹配项?事实上,给定字符串中的每个单词后面都有无限多个这样的匹配。
OpenBSD 源代码grep
(表现出与grep
macOS 上相同的行为)包含 ( src/usr.bin/grep/util.c
):
if (r == 0) {\n c = 1;\n if (oflag && pmatch.rm_so != pmatch.rm_eo)\n goto print;\n break;\n }\n }\n if (oflag)\n return c;\nprint:\n
Run Code Online (Sandbox Code Playgroud)\n\n这基本上是说,如果模式匹配 ( r == 0
) 并且我们使用-o
( oflag
),并且如果匹配开始偏移量与匹配结束偏移量相同( ,即空匹配),则不会打印pmatch.rm_so == pmatch.rm_eo
匹配结果该特定输入行上的匹配结束( “找到匹配”)。return c
c == 1
归档时间: |
|
查看次数: |
1030 次 |
最近记录: |