请教关于正则匹配0个或1个特定标签的问题

这么一段表格,匹配每一样tr中的数据

<tr class="J_RateItem">
    <td>
        <i title="我是标签"></i>
        <p>我是第1行数据</p>
    </td>
</tr>
<tr class="J_RateItem">
    <td>
        <p>我是第2行数据</p>
    </td>
</tr>

要求:

  • td中有<i>标签的时候,将td中的<p>数据,和<i>标签的取出来
  • td中没有<i>标签的时候,将td中的<p>数据取出来

于是我就下了这样的正则:

var str = `
<tr class="J_RateItem">
    <td>
        <i title="我是标签"></i>
        <p>我是第1行数据</p>
    </td>
</tr>
<tr class="J_RateItem">
    <td>
        <p>我是第2行数据</p>
    </td>
</tr>`;
console.log([
    ...str.matchAll(/<tr.+?J_RateItem.+?>.+?<td>.+?(<i.+?>)?.+?<p>(.+?)<\/p>.+?<\/td>.+?<\/tr/gs)
]);

执行结果:

  • [ok] 拿到两行tr的数据
  • [ok] 第二行没有<i>标签,返回的是undefined
  • [error] 第一行有<i>标签,返回的也是undefined

显然不符合我的预期:

  • 我试过将(<i.+?>)?换成(<i.+?>){0,1}结果是一样的
  • 而当我去掉?修饰符,变成(<i.+?>)结果只能匹配一行了

请问如何识别匹配td中的<i>标签呢?

阅读 3.5k
2 个回答

可以修改成这样,思路:用环视去掉i标签的非贪婪效果,已解决他选择什么都不匹配,但是后面也能成功匹配的后果

var str = `
<tr class="J_RateItem">
    <td>
        <i title="我是标签"></i>
        <p>我是第1行数据</p>
    </td>
</tr>
<tr class="J_RateItem">
    <td>
        <i title="我是标签"></i>
        <p>我是第1行数据</p>
    </td>
</tr>
<tr class="J_RateItem">
    <td>
        <p>我是第2行数据</p>
    </td>
</tr>`;
console.log([
    ...str.matchAll(/<tr.+?J_RateItem.+?>.+?<td>.+?(<i.+?>.*?<\/i>|(?=<p>)).*?<p>(.+?)<\/p>.+?<\/td>.+?<\/tr/gs)
]);

这种感觉直接通过dom操作更容易获取一点,如下:

[...document.querySelectorAll('.J_RateItem')].map(tr=>{
    const i = tr.querySelector('i')
    return {
        label: i && i.getAttribute('title'),
        text: tr.querySelector('p').innerText
    }
})

结果如下:

[{
    "label": "我是标签",
    "text": "我是第1行数据"
}, {
    "label": null,
    "text": "我是第2行数据"
}]
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进