三亩地 三亩地SAN MU DI · CODE DIARY
CASE STUDY · 004

Markdown 编辑器

用正则把 Markdown 语法实时转成 HTML,左侧输入右侧预览。第一次真正让字符串处理长出肌肉记忆的项目。

Markdown 编辑器界面预览
工具 · 中级

左侧敲字,右侧就变 HTML

这个项目第一次让我正儿八经写正则。# 一级标题、**加粗**、[链接](url)、`代码`、引用块、列表……每一种语法都是一条规则,每条规则就是一行正则。看上去只是字符串替换,但真写起来「贪婪匹配吞了后面所有字符」「转义顺序不对导致前面规则破坏后面规则」会让你怀疑人生。

技术栈 JavaScript / 正则
预计耗时 6 - 10 小时
难度等级 中级
核心难点 正则顺序与转义
RegExp String.replace textarea 输入 innerHTML 渲染 XSS 转义
STEPS

五步把 Markdown 跑起来

不要试图一次写完所有语法,从最简单的标题开始,逐条加规则,每加一条都立刻测试。

1

双栏布局 + 输入监听

左右两栏 grid,左是一个 <textarea>,右是一个 <div class="preview">。给 textarea 绑 input 事件,每次按键都调 render() 把转换后的 HTML 写进右侧。先用纯文本透传,确认事件通路 OK。

2

先转义 HTML,再做替换

这是最重要也最容易被忽略的一步:先把用户输入里的 < > & 替换成 &lt; 等实体,防止用户输入 <script> 直接执行(XSS)。这一步必须在所有 Markdown 规则之前做,否则后面规则生成的标签也会被转义掉。

3

逐条加规则,注意顺序

顺序原则:先处理块级(标题、引用、列表、代码块),再处理行内(加粗、斜体、链接、行内代码)。因为行内规则可能匹配到块级语法里的字符。比如先转 **粗体** 再转 `code`,否则行内代码里的 ** 会被错误地变成粗体。

4

贪婪 vs 非贪婪

**粗体** 规则时,新手会写 /\*\*(.+)\*\*/g,结果是贪婪匹配——一行里有两个粗体时,第一个 ** 会一直吃到最后一个 **。改成 /\*\*(.+?)\*\*/g(加个 ?)就是非贪婪,匹配最短可能。这是这个项目最大的坑。

5

支持代码块与列表

代码块用 /```([\s\S]+?)```/g 匹配三反引号包裹的内容,[\s\S] 是跨行匹配的小技巧(点号 . 不匹配换行)。列表先按行 split,连续 - 开头的合并成一个 <ul>。做完这两步,编辑器就基本能用了。

CODE

关键代码片段

核心转换函数,按块级 → 行内的顺序处理,每条规则都单独成行方便排错。

function md2html(src) {
  // 1. 先转义 HTML,防止 XSS
  let s = src
    .replace(/&/g, '&amp;')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;');

  // 2. 块级:代码块(先做,避免被行内规则破坏)
  s = s.replace(/```([\s\S]+?)```/g, (m, code) =>
    `<pre><code>${code.trim()}</code></pre>`);

  // 3. 块级:标题
  s = s.replace(/^### (.+)$/gm, '<h3>$1</h3>')
       .replace(/^## (.+)$/gm, '<h2>$1</h2>')
       .replace(/^# (.+)$/gm, '<h1>$1</h1>');

  // 4. 块级:引用
  s = s.replace(/^> (.+)$/gm, '<blockquote>$1</blockquote>');

  // 5. 行内:加粗、斜体、行内代码、链接(注意非贪婪 ?)
  s = s.replace(/\*\*([^*]+?)\*\*/g, '<strong>$1</strong>')
       .replace(/\*([^*]+?)\*/g, '<em>$1</em>')
       .replace(/`([^`]+?)`/g, '<code>$1</code>')
       .replace(/\[([^\]]+?)\]\(([^)]+?)\)/g, '<a href="$2">$1</a>');

  return s;
}

正则不是玄学,是「字符串版的乐高」。这个项目让我学会一件事:写正则之前先在 regex101.com 上用真实样本测一遍,把每条规则的匹配范围画出来,比盯着代码空想快十倍。所有「我这条正则怎么不工作」的疑惑,在可视化面前都会立刻现形。

—— 三亩地 · 案例笔记
NEXT

继续下一个案例

正则练完手热了,下一步我们做一个看似更简单、其实藏着状态管理精髓的计算器。

← 上一篇:天气预报小工具 下一篇:简易计算器 →
或者去小型实战项目继续练 →