如何在grep中进行非贪婪的比赛?

syk*_*ker 166 regex shell command-line grep regex-greedy

我想grey最短的比赛,模式应该是这样的:

<car ... model=BMW ...>
...
...
...
</car>
Run Code Online (Sandbox Code Playgroud)

...表示任何字符,输入是多行.

Mar*_*ers 257

你正在寻找一种非贪婪(或懒惰)的比赛.要在正则表达式中获得非贪婪的匹配,您需要?在量词之后使用修饰符.例如,您可以更改.*.*?.

默认情况下grep不支持非贪婪修饰符,但您可以使用grep -PPerl语法.

  • 在某些平台上(如Mac OS X),`grep`不支持`-P`,但是如果使用`egrep`,你可以使用`.*?`模式来实现相同的结果.`egrep -o'start.*?end'text.html` (27认同)
  • `-P`对我来说是一个全新的,我多年来一直很高兴,只使用`-E` ......这么多浪费了多年! - 注意自己:重新阅读手册页作为(甚至更多!)常规的东西,你永远不会消化足够的开关和选项. (4认同)
  • 作为@SaltyNuts注释的扩展,Mac OS X不支持`-P`但是`-E`会调用`egrep`,因此建议的`.*?`工作正常. (4认同)
  • eegg:dot all modifier也称为multiline.它是一个改变"."的修饰语.匹配行为以包括换行符(通常不包括换行符).在grep中没有这样的修饰符,但在[pcregrep](http://linuxcommand.gds.tuwien.ac.at/man_pages/pcregrep1.html)中有. (3认同)
  • 更正:在大多数支持它的正则表达式风格中,允许“.”匹配换行符的模式称为*DOTALL*或*single-line*模式;Ruby 是唯一将其称为“多行”的语言。在其他风格中,*multiline* 是允许锚点(`^` 和 `$`)在行边界匹配的模式。Ruby 没有等效的模式,因为在 Ruby 中它们总是以这种方式工作。 (2认同)

小智 81

Actualy .*?唯一的作品perl.我不确定等效的grep扩展regexp语法是什么.幸运的是,你可以使用grep的perl语法,所以grep -P可以工作,但是grep -E相同的egrep不起作用(它会贪婪).

另见:http://blog.vinceliu.com/2008/02/non-greedy-regular-expression-matching.html

  • `grep -P`在GNU grep 2.9中不起作用 - 只是尝试了它(它没有错误,只是默默地不应用`?`.也没有*不是类*例如:`env | grep'[^\=]*\="` (8认同)
  • Darwin/OS X 10.8 Mountain Lion中没有`grep -P`选项或`pgrep`命令,但`egrep`效果很好. (2认同)
  • 我的OS X 10.9机器上有一个pgrep命令,但这是一个完全不同的程序,目的是“按名称查找或发出信号”。 (2认同)

小智 11

尝试在这个帖子中的东西后,我的grep工作:

echo "hi how are you " | grep -shoP ".*? "
Run Code Online (Sandbox Code Playgroud)

只需确保为每一行添加空格即可

(我的是一行一行搜索吐出的话)

  • `-shoP`很好的助记符:) (2认同)

ken*_*orb 11

grep

对于非贪婪的匹配,grep您可以使用否定的字符类.换句话说,尽量避免使用通配符.

例如,要从页面内容中获取jpeg文件的所有链接,您可以使用:

grep -o '"[^" ]\+.jpg"'
Run Code Online (Sandbox Code Playgroud)

要处理多行,xargs首先通过管道输入.为了性能,请使用ripgrep.


小智 6

抱歉,我迟到了 9 年,但这可能对 2020 年的观众有用。

所以假设你有一行像"Hello my name is Jello". 'H'现在您想要查找以 开头和结尾的单词'o',其间可以有任意数量的字符。我们不需要台词,我们只需要文字。为此,我们可以使用以下表达式:

grep "H[^ ]*o" file
Run Code Online (Sandbox Code Playgroud)

这将返回所有单词。其工作原理是:它将允许所有字符而不是中间的空格字符,这样我们就可以避免同一行中出现多个单词。

现在您可以将空格字符替换为您想要的任何其他字符。假设初始行是"Hello-my-name-is-Jello",那么您可以使用以下表达式获取单词:

grep "H[^-]*o" file
Run Code Online (Sandbox Code Playgroud)