隔离字符串中某个单词的一个特定实例

隔离字符串中某个单词的一个特定实例

我有一个grep处理字符串的命令

test-test test

我希望该命令仅向我显示突出显示的“独立”一词test,而不是test-test.

然而,当我跑步时

echo "test-test test" | grep -w "test"

我突出test显示了所有发生的情况。

是否可以将匹配限制为仅孤立出现test

答案1

所有test出现的内容都以粗体显示,因为-w单词是由非单词字符分隔的单词字符序列,单词字符是字母数字和下划线。-不是单词字符。

在 中testing-test+test2;test_3;untested,只有第二个test匹配项匹配,因为这是唯一一个前面或后面都没有单词字符的匹配项。

如果您想匹配以空格分隔的单词,则必须指定这些环视四周手动断言,并且您需要与 perl 兼容的正则表达式来实现并非所有grep实现都支持的功能。由于您似乎有一个grep='grep --color别名,如果您grep支持--color,那么它也有可能支持-P/-X perl选项,然后您可以执行以下操作:

grep --color -P '(?<!\S)test(?!\S)'

(?<!...)(?!...)分别是Perl 正则表达式中的负向后看和向前看断言运算符\S,就像 POSIX 的[^[:space:]]匹配和不属于空白的字符。这就是说:“test只要它前面或后面都没有非空白字符,就匹配”。

答案2

使用 Perl 正则表达式(在带有-P标志的 GNU grep 中受支持),您可以使用负向后查找和向前查找来断言 的匹配test不与 相邻-

echo "test-test test" | grep -P '(?<!-)test(?!-)'

这输出

测试一下测试

答案3

使用扩展的正则表达式,你可以像这样实现它

grep -E "(^| )test( |$)"

需要注意的是,这实际上会突出显示任何前导或训练空间,但您不会看到它,因为它不是可打印的字符。

答案4

使用珀尔:

~$ echo "test-test test\ntest\n\n" | perl -lpe 's/(?<!\S)(test)(?!\S)/**$1**/g;'
test-test **test**
**test**


使用:

~$ echo "test-test test\ntest\n\n" | raku -pe 's:g/ <!after \S > (test) <!before \S >  /**$0**/;'
test-test **test**
**test**


[特别感谢@StéphaneChazelas 在他的grep回答中对 Perl 风格的 Lookarounds 的阐述]。

如果你想要类似于突出显示的东西,这里有一个简单的想法珀尔蒙克斯grep使用 Perl/Raku 并用星号包围匹配项,而不是的颜色选项**

afterRaku 注:Lookbehinds在 Raku 中拼写?为积极和消极,而 Lookaheads在 Raku 中!拼写为积极和消极。所以你可以直接阅读上面的 Raku 代码:before?!“全局替换单词“test”的任何匹配项,而不after是非空白字符,也不是非before空白字符......”。

https://perldoc.perl.org/perlre#Lookaround-Assertions
https://docs.raku.org/language/regexes#Lookahead_assertions
https://docs.raku.org/language/regexes#Lookbehind_assertions

相关内容