如何在grep中做一个非贪婪的匹配?
我想grep最短的比赛,模式应该是这样的:
<car ... model=BMW ...> ... ... ... </car>
…意味着任何字符和input是多行。
你正在寻找一个非贪婪(或懒惰)的比赛。 要在正则expression式中获得非贪婪的匹配,您需要使用修饰符?
量词后。 例如,你可以改变.*
到.*?
。
默认情况下, grep
不支持非贪婪修饰符,但可以使用grep -P
来使用Perl语法。
实际上.*?
只在perl
。 我不知道等效的grep扩展正则expression式语法是什么。 幸运的是,你可以在grep中使用perl语法,所以grep -P
可以工作,但是grep -E
和egrep
一样,不会工作(这将是贪婪的)。
另见: 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匹配的相同文本