C#如何转义*_()[]字符且不破坏Markdown []()链接结构
问题原因
你原有正则的负向零宽断言存在两处缺陷:
- 贪婪匹配
.*无法准确界定链接边界,匹配范围不可控 - 仅排除了「位于链接前缀之后」的字符,没有区分字符本身是否属于链接结构的组成部分,导致链接的
[]()也被错误转义
解决方案
采用「优先匹配保留完整链接,再转义其余特殊字符」的逻辑实现,不需要写复杂的零宽断言,逻辑更稳定:
using System.Text.RegularExpressions; string input = "text, *text*, text, text, (text), [text], [some_text with _ * ](http://.....) *text*, text, text, (text), [text]"; // 正则规则:第一组优先匹配完整的markdown链接结构,第二组匹配需要转义的单个特殊字符 string pattern = @"(\[.*?\]\(.*?\))|([\[\]()*_])"; string output = Regex.Replace(input, pattern, match => { // 匹配到完整链接直接返回原内容,不做转义 if (match.Groups[1].Success) { return match.Groups[1].Value; } // 匹配到单独特殊字符,添加转义符 return $@"\{match.Groups[2].Value}"; });
正则中使用.*?非贪婪匹配,保证只会匹配最短的符合要求的链接,不会出现多个链接被合并匹配的问题,运行结果和你要求的期望输出完全一致。
内容的提问来源于stack exchange,提问作者rainyDa
相关产品推荐
相关产品推荐

