我想 grep 最短的匹配,模式应该是这样的:
<car ... model=BMW ...>
...
...
...
</car>
... 表示任何字符,输入是多行。
我想 grep 最短的匹配,模式应该是这样的:
<car ... model=BMW ...>
...
...
...
</car>
... 表示任何字符,输入是多行。
You're looking for a non-greedy (or lazy) match. To get a non-greedy match in regular expressions you need to use the modifier ?
after the quantifier. For example you can change .*
to .*?
.
By default grep
doesn't support non-greedy modifiers, but you can use grep -P
to use the Perl syntax.
实际上,.*?
唯一适用于perl
. 我不确定等效的 grep 扩展正则表达式语法是什么。幸运的是,您可以将 perl 语法与 grep 一起使用,这样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 ".*? "
只需确保在每一行都附加一个空格
(我的是逐行搜索吐词)
grep
对于非贪婪匹配,grep
您可以使用否定字符类。换句话说,尽量避免使用通配符。
例如,要从页面内容中获取所有指向 jpeg 文件的链接,您可以使用:
grep -o '"[^" ]\+.jpg"'
要处理多行,xargs
请先通过管道输入。为了性能,使用ripgrep
.
对不起,我迟到了 9 年,但这可能对 2020 年的观众有用。
所以假设你有一条像"Hello my name is Jello"
. 现在您要查找以 开头'H'
和结尾的单词,'o'
中间包含任意数量的字符。我们不想要线条,我们只想要文字。因此,我们可以使用以下表达式:
grep "H[^ ]*o" file
这将返回所有单词。它的工作方式是:它将允许所有字符而不是空格字符,这样我们可以避免在同一行中出现多个单词。
现在您可以用您想要的任何其他字符替换空格字符。假设初始行是"Hello-my-name-is-Jello"
,那么您可以使用以下表达式获取单词:
grep "H[^-]*o" file
简短的回答是使用下一个正则表达式:
(?s)<car .*? model=BMW .*?>.*?</car>
一个(稍微)更复杂的答案是:
(?s)<([a-z\-_0-9]+?) .*? model=BMW .*?>.*?</\1>
这将使得在以下文本中匹配 car1 和 car2 成为可能
<car1 ... model=BMW ...>
...
...
...
</car1>
<car2 ... model=BMW ...>
...
...
...
</car2>
我知道这有点过时了,但我只是注意到这是可行的。它从我的输出中删除了清理和清理。
> grep -v -e 'clean\-\?up'
> grep --version grep (GNU grep) 2.20