如何用正则匹配末列含up/down的HTML行并添加背景样式
正则匹配HTML表格行并添加样式实现方案
问题背景
现有HTML表格结构示例如下:
<tr> ... </tr> <tr> <td class="text">M-GOOG-NYC-03-SW01</td> <td class="text"><a href="/event-reporter?child=ping4;device=limit=1000;mode=table+graph;navbar=off;refresh=60;sort=lastchange;sort_dir=f;time=last4h; return false;">8.8.8.8</a></td> <td class="comma">2</td> <td class="elapsed"><div data-toggle="tooltip" data-placement="bottom" title="Last Change: Sun, Oct 17, 2021 at 09:16">2 mins 14 secs</div></td> <td class="text">up</td> </tr> <tr> ... </tr>
需求为匹配最后一列<td class="text">内容为up或down的<tr>行,满足条件时为行首第一个<td>插入背景色样式,或者直接为整行<tr>插入背景样式。
之前尝试的正则存在两个问题:要么仅能匹配到一个实例,要么匹配到第一个<tr>后跳过中间行,匹配到其他行的</tr>结束。
问题原因
此前使用的[\s\S]*为贪婪匹配,会尽可能匹配最长的内容,所以会跨多个<tr>行匹配导致范围错误。同时锚点设置没有限制单个<tr>内部的范围,也会导致匹配溢出。
正确实现方案
1. 仅修改首列样式的正则实现
使用非贪婪匹配,同时限制匹配范围在单个<tr>内部,代码如下:
// 匹配状态为up的行,首列加橙色背景 htmlStr = htmlStr.replace(/(<tr>\n\s*<td class="text")>(.*?<td class="text">up<\/td>\s*<\/tr>)/gims, '$1 style="background-color:#FFCC99">$2'); // 匹配状态为down的行,首列加红色背景,可根据需求自定义颜色 htmlStr = htmlStr.replace(/(<tr>\n\s*<td class="text")>(.*?<td class="text">down<\/td>\s*<\/tr>)/gims, '$1 style="background-color:#FFCCCC">$2');
正则说明:
- 修饰符
g:全局匹配所有符合条件的行 - 修饰符
i:忽略大小写,可根据实际HTML结构决定是否移除 - 修饰符
m:开启多行匹配 - 修饰符
s:让.可以匹配换行符,替代之前的[\s\S]写法 .*?:非贪婪匹配,保证只匹配到当前行的</tr>就停止,不会跨多行- 分组
$1捕获首列<td>的开头部分,直接在后面拼接style属性即可,不需要修改原有内容
2. 整行添加背景样式的实现
如果需要给整个<tr>加背景,调整正则如下:
// up状态整行加橙色背景 htmlStr = htmlStr.replace(/(<tr)>(\s*<td.*?<td class="text">up<\/td>\s*<\/tr>)/gims, '$1 style="background-color:#FFCC99">$2'); // down状态整行加红色背景 htmlStr = htmlStr.replace(/(<tr)>(\s*<td.*?<td class="text">down<\/td>\s*<\/tr>)/gims, '$1 style="background-color:#FFCCCC">$2');
注意事项
如果HTML结构中存在注释、特殊换行或者td属性顺序变化的情况,正则的适配性会下降,复杂场景推荐使用DOM解析的方式处理,性能和兼容性更好。
内容的提问来源于stack exchange,提问作者quarkz
相关产品推荐
相关产品推荐

