如何实现自定义BBCode?支持类WhatsApp的粗体斜体等格式标记
实现代码
// 定义标记与对应HTML标签的映射表,可按需扩展 const tagMap = { '*': 'strong', // 粗体 '_': 'i', // 斜体 '~': 'del', // 删除线 '-': 'u' // 下划线 } // 统一匹配正则:反向引用保证前后标记一致,\s*兼容标记与内容间的任意空格 const bbcodeReg = new RegExp(`([${Object.keys(tagMap).join('')}])\\s*(.*?)\\s*\\1`, 'gi') // 测试用例 let data = '* * Bold this * and _ italise this _ ~ 删除线测试 ~ - 下划线测试 -' // 单次replace完成所有格式转换 data = data.replace(bbcodeReg, (match, marker, content) => { return `<${tagMap[marker]}>${content}</${tagMap[marker]}>` })
方案说明
- 解决了标记与内容之间存在空格无法匹配的问题:正则里的
\s*会自动忽略标记和内容前后的多余空格,内容中间的空格会完整保留 - 仅调用一次
replace完成所有格式转换,不需要链式调用多次替换 - 扩展新格式非常方便,只需要在
tagMap里新增标记和对应HTML标签即可,不需要修改正则逻辑 - 如果需要支持多字符标记(比如用
**表示粗体、__表示下划线),只需要调整正则匹配优先级,把长标记放在前面即可,示例如下:
const tagMap = { '**': 'strong', '__': 'u', '*': 'i', '~': 'del' } // 正则先匹配长标记,再匹配短标记 const bbcodeReg = /(\*\*|__|\*|~)\s*(.*?)\s*\1/gi
内容的提问来源于stack exchange,提问作者The concise
相关产品推荐
相关产品推荐

