必须转义的字符包括反斜杠、星号*、下划线_、大括号{}、方括号[]、圆括号()、井号#、加号+、减号-、点.、感叹号!、竖线|、反引号`,共14个,需在前加反斜杠以防止被解析为格式标记。

哪些字符必须转义才能在Markdown中安全显示
Markdown解析器对某些字符有特殊含义,比如 *、_、[、]、(、)、#、+、-、!、`、 等。如果用户输入的字符串里包含这些符号,又不希望它们被解析为格式标记(比如把 foo_bar 渲染成斜体),就必须加反斜杠转义。
注意:不是所有符号都需要无条件转义——比如在代码块或行内代码中,` 就不该被转义;但如果你只是做「纯文本到普通段落」的转换,最稳妥的做法是统一转义所有 Markdown 元字符。
-
必须最先处理,否则后续转义会出错(比如先把*变成*,再处理时可能变成\*) -
`和~在部分解析器中影响 GFM 表格/删除线,建议一并转义 和 <code>>虽然不是标准 Markdown 元字符,但在 HTML 上下文中可能引发问题,视使用场景决定是否加入
用 std::string::replace 实现逐字符转义的陷阱
直接遍历字符串、对每个元字符调用 std::string::replace 是常见写法,但容易因索引偏移出错——每次插入 后,后续字符位置都变了,而循环变量还在递增。
更可靠的方式是反向遍历,或构建新字符串:
std::string escape_markdown(const std::string& s) {
std::string out;
out.reserve(s.size() * 2); // 预分配避免频繁 realloc
for (char c : s) {
switch (c) {
case '\': case '*': case '_': case '{': case '}':
case '[': case ']': case '(': case ')': case '#':
case '+': case '-': case '.': case '!': case '`':
out += '\';
[[fallthrough]];
default:
out += c;
}
}
return out;
}
这个实现避开了索引管理问题,也比反复 replace 快。注意 case '' 必须放在最前,且用 [[fallthrough]] 让它也走默认分支加自身,否则会漏掉反斜杠本身。
Web fetch markdown of page
下载
通过 jina.ai 将网页抓取为精简的 markdown,用于在需要获取 URL 并获取压缩的 markdown 内容以节省 token。触发词 l...
要不要处理 Unicode 或控制字符
标准 Markdown 规范不定义 Unicode 转义行为,但实际中:std::string 存的是 UTF-8 字节流,上面的逐字节处理完全可行——只要你不把多字节 UTF-8 序列当单个字符切开(而我们的 for (char c : s) 正是按字节遍历,所以安全)。
真正要小心的是控制字符(如
