如何在grep中做一个非贪婪的匹配?

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

<car ... model=BMW ...> ... ... ... </car> 

…意味着任何字符和input是多行。

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

默认情况下, grep不支持非贪婪修饰符,但可以使用grep -P来使用Perl语法。

实际上.*? 只在perl 。 我不知道等效的grep扩展正则expression式语法是什么。 幸运的是,你可以在grep中使用perl语法,所以grep -P可以工作,但是grep -Eegrep一样,不会工作(这将是贪婪的)。

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

我的grep在尝试了这个线程中的东西之后工作:

 echo "hi how are you " | grep -shoP ".*? " 

只要确保你为每一行添加一个空格

(我的是一行一行的search吐字)

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

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

 grep -o '"[^" ]\+.jpg"' 

简短的回答是使用下一个正则expression式:

 (?s)<car .*? model=BMW .*?>.*?</car> 
  • (?s) – 这使得跨多行匹配
  • 。*? – 匹配任何字符,懒惰的次数(最小匹配)

一个(小)更复杂的答案是:

 (?s)<([az\-_0-9]+?) .*? model=BMW .*?>.*?</\1> 

这将有可能在以下文本中匹配car1和car2

 <car1 ... model=BMW ...> ... ... ... </car1> <car2 ... model=BMW ...> ... ... ... </car2> 
  • (..)代表一个捕获组
  • \ 1在这个上下文中匹配最近与捕获组号1匹配的相同文本