我想要最短的比赛,模式应该是这样的:
<car ... model=BMW ...>
...
...
...
</car>
...表示任何字符,输入是多行。
答案 0 :(得分:233)
你正在寻找一种非贪婪(或懒惰)的比赛。要在正则表达式中获得非贪婪匹配,您需要在量词之后使用修饰符?
。例如,您可以将.*
更改为.*?
。
默认情况下grep
不支持非贪婪修饰符,但您可以使用grep -P
来使用Perl语法。
答案 1 :(得分:79)
Actualy .*?
仅适用于perl
。我不确定等效的grep扩展regexp语法是什么。幸运的是,您可以使用grep的perl语法,因此grep -P
可以正常工作,但与grep -E
相同的egrep
将不起作用(这将是贪婪的)。
另请参阅:http://blog.vinceliu.com/2008/02/non-greedy-regular-expression-matching.html
答案 2 :(得分:10)
grep
对于grep
中的非贪婪匹配,您可以使用否定的字符类。换句话说,尽量避免使用通配符。
例如,要从页面内容中获取jpeg文件的所有链接,您可以使用:
grep -o '"[^" ]\+.jpg"'
要处理多行,请先通过xargs
管道输入。为了提高性能,请使用ripgrep
。
答案 3 :(得分:9)
我的grep在尝试了这个帖子中的东西之后有效:
echo "hi how are you " | grep -shoP ".*? "
确保为每一行添加空格
(我的是逐行搜索以吐出单词)
答案 4 :(得分:1)
对不起,我迟到了9年,但这可能会在2020年使观众受益。
因此,假设您有一行"Hello my name is Jello"
。
现在,您要查找以'H'
开头和以'o'
结尾的单词,中间包含任意数量的字符。而且我们不想要线条,我们只想要单词。为此,我们可以使用表达式:
grep "H[^ ]*o" file
这将返回所有单词。这样做的方式是:允许所有字符代替中间的空格,这样就可以避免同一行中出现多个单词。
现在,您可以将空格字符替换为所需的任何其他字符。
假设第一行是"Hello-my-name-is-Jello"
,则可以使用以下表达式获取单词:
grep "H[^-]*o" file
答案 5 :(得分:0)
简短的回答是使用下一个正则表达式:
(?s)<car .*? model=BMW .*?>.*?</car>
一个(小)更复杂的答案是:
(?s)<([a-z\-_0-9]+?) .*? model=BMW .*?>.*?</\1>
这样就可以在以下文字中匹配car1和car2
<car1 ... model=BMW ...>
...
...
...
</car1>
<car2 ... model=BMW ...>
...
...
...
</car2>
答案 6 :(得分:-1)
我知道帖子有点死了,但我只是注意到这可行。它从我的输出中删除了清理和清理。
> grep -v -e 'clean\-\?up'
> grep --version grep (GNU grep) 2.20