如何用JavaScript和正则遍历HTML,替换Anki标注文本并设置加粗?
解决Anki中Callout标题的替换问题
需求场景
现有Anki卡片背面的HTML内容如下:
<p>[!Quote] Title of callout 1<br>Content of callout 1</p> <p>[!Quote] Title of callout 2<br>Content of callout 2</p> <p>[!Quote] Title of callout 3<br>Content of callout 3</p>
需要将其修改为:移除[!Quote]标记,并将标题部分设置为加粗格式,最终效果如下:
<p><b>Title of callout 1</b><br>Content of callout 1</p> <p><b>Title of callout 2</b><br>Content of callout 2</p> <p><b>Title of callout 3</b><br>Content of callout 3</p>
原代码问题分析
原代码用match()获取所有标题后,直接将数组转成逗号分隔的字符串进行替换,导致所有标题被一次性插入到第一个匹配位置,出现错误结果。
解决方案
方案1:带捕获组的正则一次性替换
利用正则捕获组特性,让replace()自动匹配并替换每个独立标题:
const back = document.getElementById('back'); // 正则匹配<p>开头的[!Quote]及后续标题,捕获标题内容 const replaceRegex = /<p>\[!Quote]\s*(.*?)(?=<br>)/g; back.innerHTML = back.innerHTML.replace(replaceRegex, '<p><b>$1</b>');
- 正则说明:
<p>\[!Quote]\s*:匹配<p>开头的[!Quote]及后续空白字符(.*?):非贪婪捕获标题文本(直到<br>前结束)(?=<br>):正向预查,确保匹配范围截止到<br>前
$1对应每个捕获到的标题,替换时会自动对应每个匹配项。
方案2:遍历DOM元素逐个处理(更稳妥)
直接操作每个<p>元素,避免批量修改innerHTML的潜在问题:
const back = document.getElementById('back'); const paragraphs = back.querySelectorAll('p'); paragraphs.forEach(para => { const originalHtml = para.innerHTML; // 替换当前段落的[!Quote]标记并加粗标题 const updatedHtml = originalHtml.replace(/^\[!Quote]\s*(.*?)(?=<br>)/, '<b>$1</b>'); para.innerHTML = updatedHtml; });
- 此方法逐个处理段落,逻辑清晰,适配更复杂的DOM结构场景。
内容的提问来源于stack exchange,提问作者lukaskupfing
相关产品推荐
相关产品推荐

