如何用sed移除全局模式中的“小型”模式?HTML处理异常排查
解决sed处理HTML标签时的数据丢失问题
你遇到的问题是sed默认的贪婪正则匹配导致的——原来的命令里</td>.*<td>会从第一个</td>开始,一直匹配到最后一个<td>的位置,直接把中间的<td>456</td>也给删掉了,当然会丢数据啦!
正确的sed命令写法
我们可以用非贪婪匹配的替代写法来解决,因为sed的基础正则不支持.*?这种非贪婪语法,换用[^<]*来匹配<之前的所有内容,这样就不会跨过下一个<td>标签:
sed 's#</td>[^<]*<td>#</td><td>#g' tmp.html
或者用转义/的版本(可读性稍差):
sed 's/<\/td>[^<]*<td>/<\/td><td>/g' tmp.html
效果验证
输入的tmp.html内容:
<table><td>123</td>1<td>456</td>2<td>789</td></table>
执行命令后输出:
<table><td>123</td><td>456</td><td>789</td></table>
完美符合你的需求,只移除了</td>和<td>之间的冗余文本(例子里的1和2),保留了所有有效<td>标签内容。
原理说明
[^<]*是正则里的否定字符集,表示匹配任意数量的不是<的字符,这样当匹配到下一个<td>的<时就会停止,避免了贪婪匹配跨过多标签的问题。
内容的提问来源于stack exchange,提问作者user270199
相关产品推荐
相关产品推荐

