sanitize-html合并连续<br>标签失败,求代码修改方案
sanitize-html合并连续
标签问题的原因与解决方案
标签问题的原因与解决方案
问题现象
使用sanitize-html时,输入包含连续\n的字符串能被textFilter合并为单个<br>,但输入包含连续<br>标签的字符串时,输出仍保留多个连续<br>,无法合并。
原因分析
sanitize-html的textFilter仅作用于文本节点内容,而<br>是独立的HTML标签节点,不属于文本内容范畴:
- 当输入是
\n\n时,这属于文本内容,会进入textFilter被正则替换; - 当输入是
<br><br>时,这些会被解析为两个独立的<br>标签节点,不会经过textFilter处理,所以正则匹配不到它们。
另外你的代码里存在一个明显错误:const href = href会导致无限引用,应该改为const href = attribs.href。
修改方案
使用postProcess钩子,在整个HTML处理完成后,对最终的HTML字符串进行全局替换,合并连续的<br>标签:
import sanitizeHtml from 'sanitize-html'; const allowedTags = [ 'h1', 'h2', 'h3', 'h4', 'h5', 'p', 'a', 'strong', 'i', 'ul', 'ol', 'li', 'em', 'br', ]; export const sanitizeEventDescription = ( description: string, keepNewline: boolean ) => sanitizeHtml(description, { allowedTags, transformTags: { a: function transform(tagName, attribs) { // 修复原代码的href引用错误 const href = attribs.href; return { tagName: 'a', attribs: { ...attribs, href, target: '_blank', rel: 'noopener noreferrer', }, }; }, }, exclusiveFilter(frame) { return !frame.text.trim() && frame.tag !== 'br'; }, textFilter(text) { // 处理文本中的换行符,转为<br> return text.replace(/\n+/g, '<br>'); }, // 添加postProcess处理连续的<br>标签 postProcess(html) { // 匹配连续的<br>标签(包括不同写法及标签间空白) return html.replace(/(<br\s*\/?>)\s*(?=<br\s*\/?>)/g, ''); }, });
说明
postProcess会接收处理完成后的最终HTML字符串,此时所有标签都已处理完毕,可通过正则全局替换连续的<br>;- 正则
/(<br\s*\/?>)\s*(?=<br\s*\/?>)/g兼容<br>、<br/>、<br />等写法,同时能过滤标签间的空白字符,确保连续标签被合并为单个; - 修复了原代码中
const href = href的错误,避免运行时异常。
内容的提问来源于stack exchange,提问作者Roman Prokopets
相关产品推荐
相关产品推荐

