7

我正在编写一个分析 html 文件的 bash 脚本,我想获取每个<tr>...</tr>. 所以我的命令看起来像:

$ tr -d \\012 < price.html | grep -oE '<tr>.*?</tr>'

但这似乎grep给了我以下结果:

$ tr -d \\012 < price.html | grep -oE '<tr>.*</tr>'

我怎样才能做到.*不贪心?

4

4 回答 4

17

如果你有GNU Grep你可以使用-P使匹配非贪婪:

$ tr -d \\012 < price.html | grep -Po '<tr>.*?</tr>'

该选项启用非贪婪匹配所需的-PPerl 兼容正则表达式(PCRE)? ,因为基本正则表达式(BRE)和扩展正则表达式(ERE)不支持它。

如果您正在使用-P,您还可以使用环视来避免在匹配中打印标签,如下所示:

$ tr -d \\012 < price.html | grep -Po '(?<=<tr>).*?(?=</tr>)'

如果您没有GNU grep并且 HTML 格式正确,您可以这样做:

$ tr -d \\012 < price.html | grep -o '<tr>[^<]*</tr>'

注意:上面的示例不适用于<tr>.

于 2013-10-01T20:25:19.267 回答
4

非贪婪匹配不是grep -E. grep -P如果你有,请改用,或者切换到 Perl / Python / Ruby / 你有什么。(哦,还有pcregrep。)

当然,如果你真的是说

<tr>[^<>]*</tr>

你应该这样说;那么普通的旧的grep就可以了。

您可以(繁琐地)扩展正则表达式以接受嵌套标签,<tr>但当然,最好使用适当的 HTML 解析器,而不是花大量时间重新发现为什么正则表达式不是正确的工具。

于 2013-10-01T20:26:21.403 回答
3

.*?是一个 Perl 正则表达式。改变你grep

grep -oP '<tr>.*?</tr>'
于 2013-10-01T20:25:25.420 回答
3

尝试 perl 风格的正则表达式

$ grep -Po '<tr>.*?</tr>' input
<tr>stuff</tr>
<tr>more stuff</tr>
于 2013-10-01T20:25:49.047 回答