Markdown 转义字符完全指南
写 Markdown 的时候,有没有遇到过这样的情况——明明输入的是 *hello*,结果渲染出来变成了 hello(斜体)?或者写 # 标题,结果被当成了真正的标题?
这就是 Markdown 的"特殊字符"在搞鬼。像星号、井号、方括号这些符号,在 Markdown 中都有格式化功能。如果你想让他们乖乖地以原始面目示人,就需要用到 Markdown 转义(escape)。
什么是 Markdown 转义?
转义的本质很简单:在特殊字符前面加一个反斜杠 \,告诉 Markdown 解析器"这个符号别处理,原样显示"。
比如:
\*这不是斜体\*渲染结果是:*这不是斜体*(星号原样显示,不会变成斜体)。
这个规则来自 Markdown 的原始设计——John Gruber 在最初的语法文档中就定义了反斜杠转义机制 [^1]。
哪些字符可以转义?完整列表
下面是 Markdown 支持转义的全部字符:
| 字符 | 名称 | 常见用途 |
|---|---|---|
\ | 反斜杠 | 转义本身 |
` | 反引号 | 行内代码 |
* | 星号 | 加粗/斜体 |
_ | 下划线 | 加粗/斜体 |
{} | 花括号 | 部分扩展语法 |
[] | 方括号 | 链接/图片 |
() | 圆括号 | 链接 |
# | 井号 | 标题 |
+ | 加号 | 无序列表 |
- | 减号/连字符 | 无序列表/分割线 |
. | 句号 | 有序列表 |
! | 感叹号 | 图片 |
| | 管道符 | 表格(扩展语法)[^2] |
一共 13 个字符(管道符 | 在部分解析器中支持)。说实话这个列表不长,但几乎覆盖了所有会"捣乱"的符号。
管道符的特殊情况
管道符 | 是个需要单独说一下的字符。在标准 Markdown 中它没有特殊含义,但如果你用了表格语法(GitHub Flavored Markdown 扩展),管道符就是表格列的分隔符。所以在表格内容中显示管道符,需要转义:
| 命令 | 说明 |
|------|------|
| `ls \| grep test` | 列出文件并过滤 |不过在代码块里写管道符是不需要转义的,这一点后面会说。
常见转义场景
显示星号和下划线
这是最常见的场景。当你在写数学公式或普通文本时,经常需要显示原始的星号或下划线:
分数计算:score \= 100 \* 0.8 \+ 20
文件路径:C:\\Users\\\_sunson\\\_docs渲染结果中,星号和下划线都会原样显示,不会被解析为加粗或斜体。
显示井号(不被当成标题)
在讨论议题编号、颜色代码等场景中,经常需要显示 #:
今天讨论的议题是 \#42 和 \#108
背景色使用 \#FFFFFF显示方括号和圆括号
当你在文本中需要展示链接语法本身,而不是一个真正的链接时:
链接语法格式是:\[显示文字\]\(URL\)不用反斜杠的转义方法
反斜杠是最常用的转义方式,但不是唯一的。根据场景,还有几个替代方案。
用行内代码包裹
把内容放在反引号 ` 里面,所有特殊字符都不会被解析:
`**不会加粗**` → **不会加粗**(原样显示)
`# 不是标题` → # 不是标题
`[不是链接](url)` → [不是链接](url)这是我最推荐的方式——当你只是想让某个片段原样显示时,行内代码比逐个字符加反斜杠方便得多。特别是在写技术文档的时候,代码本身就是用反引号标记的,一举两得。
用代码块
如果是多行内容需要原样展示,用三个反引号的代码块就行:
```markdown
**这段文字不会加粗**
## 这不是标题
[这不是链接](https://example.com)
在代码块里,Markdown 的格式化功能完全失效,所有字符原样显示,不需要任何转义。
### 用 HTML 实体
对于 `<` 和 `>` 这两个符号,有时候用 HTML 实体更稳妥:
```markdown
<div> → <div>(原样显示)
5 > 3 → 5 > 3HTML 实体 < 表示 <,> 表示 > [^3]。在部分解析器中,直接写 < 可能被当成 HTML 标签处理,用实体可以避免这个问题。
代码块嵌套:一个容易踩的坑
这个话题稍微深入一点。当你在 Markdown 中需要"展示一段 Markdown 代码",也就是代码块里包含代码块时,会遇到转义的嵌套问题。
基本思路:用更多反引号
外层代码块用比内层更多的反引号就行。比如内层是三个反引号,外层就用四个:
````markdown
```javascript
console.log("hello");
另一个选择:用波浪线
除了反引号,还可以用 ~~~ 作为代码块的定界符,这样就不会和反引号冲突:
```javascript
console.log("hello");
```有一次我在 GitHub 上写教程,需要展示一个包含代码块的 Markdown 示例,结果三个反引号嵌套直接把渲染搞乱了。后来改用四个反引号才解决。说实话这个问题不常遇到,但遇到了就很头疼——Rick Strahl 在他的博客中也详细讨论过这个"套娃式"的嵌套方案 [^4]。
行内代码中转义反引号
这个是 Stack Exchange 上一个 37 万浏览量的经典问题 [^5]。在行内代码里,你没法用反斜杠转义反引号(因为行内代码内不处理转义)。解决方案是用双反引号包裹:
`` ` `` → ` (显示一个反引号)
`` `` ` `` `` → `` ` `` (显示两个反引号)注意双反引号和内容之间加一个空格,这样开头的反引号才不会被当成结束标记。
不同平台的差异
这是很多人容易忽略的一点:不同的 Markdown 解析器对转义的支持是有差异的。
| 字符 | CommonMark | GFM (GitHub) | Obsidian | Typora |
|---|---|---|---|---|
| 基本转义(13字符) | ✅ | ✅ | ✅ | ✅ |
管道符 \| | ✅ | ✅ | ✅ | ✅ |
| 表格内转义 | ✅ | ✅ | ⚠️ 部分支持 | ✅ |
行末 \ 换行 | ✅ | ✅ | ✅ | ✅ |
| 转义空格 | ✅ (non-breaking) | ✅ | ✅ | ✅ |
大部分基础转义在所有平台上都能正常工作。差异主要体现在一些边缘场景,比如表格内的转义和某些扩展语法中。Yihui 在 R Markdown Cookbook 中也提到过,转义空格会生成"不换行空格"(non-breaking space),这个行为在不同环境中效果可能略有不同 [^6]。
常见问题
转义了但不生效怎么办?
首先确认两件事:
是不是在代码块里加的反斜杠? 代码块内反斜杠不会被解释为转义,它就是普通字符。如果要在代码块里显示反斜杠,直接写就行,不需要额外转义。
反斜杠后面是不是可转义字符? Markdown 只对上面列表里的 13 个字符生效。如果你写
\a或\b,反斜杠和字母都会原样显示,不会有任何变化。
怎么显示反斜杠本身?
反斜杠自身的转义就是两个反斜杠:
\\ → \如果要显示多个反斜杠,就是成对使用:\\\\ → \\。
行末反斜杠是什么意思?
在行末加一个反斜杠表示"软换行",相当于在下一行继续当前段落,而不是新起一个段落:
这是一段很长的文字,\
但在渲染时它们会连在一起显示。这个用法来自 CommonMark 规范,在 GitHub、Obsidian、Typora 中都支持 [^1]。
表格里怎么显示管道符?
在表格的单元格中显示管道符,用反斜杠转义:
| 命令 | 说明 |
|------|------|
| `a \|\| b` | 逻辑或运算 |或者把包含管道符的内容放在代码标记里(行内代码或代码块),这样也不需要手动转义。
速查表
最后放一张速查表,方便需要的时候快速查找:
| 想显示的字符 | 写法 | 说明 |
|---|---|---|
\ | \\ | 反斜杠 |
` | \` 或双反引号包裹 | 反引号 | |
* | \* | 星号 |
_ | \_ | 下划线 |
# | \# | 井号 |
+ | \+ | 加号 |
- | \- | 减号 |
. | \. | 句号 |
! | \! | 感叹号 |
[] | \[ \] | 方括号 |
() | \( \) | 圆括号 |
{} | \{ \} | 花括号 |
\| | \| | 管道符 |
< | < | HTML 实体 |
> | > | HTML 实体 |
相关内容
- Markdown 加粗语法 — 了解星号和下划线的格式化功能
- Markdown 代码块 — 代码块语法详解,天然的"免转义区"
- Markdown 表格语法 — 表格中管道符的用法
- Markdown 链接语法 — 链接中方括号和圆括号的作用
[^1]: John Gruber, "Markdown Syntax Documentation," Daring Fireball. https://daringfireball.net/projects/markdown/syntax[^2]: Markdown Guide, "Basic Syntax." https://www.markdownguide.org/basic-syntax[^3]: MDtoLink Blog, "Markdown Escape Characters: The Complete List." https://mdtolink.com/blog/markdown-escape-characters/[^4]: Rick Strahl, "Escaping Markdown Code Snippets and Inline Code as Markdown," West Wind Weblog, 2022. https://weblog.west-wind.com/posts/2022-Feb-16-Escaping-Markdown-Code-Snippets-and-Inline-Code-as-Markdown[^5]: Stack Exchange Meta, "How do I escape a backtick within in-line code in Markdown?" https://meta.stackexchange.com/questions/82718[^6]: Yihui Xie, "Special Characters," R Markdown Cookbook. https://yihui.org/rmarkdown-cookbook/special-chars