如何用JavaScript实现正则替换不在反引号内的Markdown特殊字符
解决方案
你原有的正则没有区分反引号内外区域,所以会错误转义代码块内部的特殊字符。由于JavaScript正则的可变长度负向断言支持有限,我们采用优先匹配反引号包裹块、跳过不处理,仅处理非反引号区域特殊字符的方案,通过replace的回调函数实现逻辑分支。
实现代码
const escapedMarkdown = rawMarkdown.replace( /(```[\s\S]*?```|`[^`]*`)|([*_{}\[\]()#+.!-])/g, (match, codeBlock, specialChar) => { // 匹配到反引号包裹的代码块直接返回原内容 if (codeBlock) return codeBlock; // 仅对非代码块的特殊字符做转义 return `\\${specialChar}`; } );
正则说明
- 第一分组
(```[\s\S]*?```|[^`]*`)`:优先匹配两类代码块,优先级高于后面的特殊字符匹配- 三重反引号包裹的多行内容:
[\s\S]*?惰性匹配所有字符直到遇到下一个三重反引号 - 单反引号包裹的行内代码:
[^]*`匹配所有非反引号字符直到遇到下一个单反引号
- 三重反引号包裹的多行内容:
- 第二分组
([*_{}\[\]()#+.!-]):匹配所有需要转义的Markdown特殊字符,将-放在字符集末尾避免被识别为范围符
示例验证
- 示例1输入:
foobarbaz.quxquux输出:`foo `bar` baz\.qux `quux,仅转义行内文本中的.,反引号内内容无变化 - 示例2输入:
foobar.bazfoo_bar
输出:foobar.bazfoo\_bar,仅转义行内文本中的_,反引号内的.保留原样
内容的提问来源于stack exchange,提问作者cgiroux86
相关产品推荐
相关产品推荐

