正则实现轻量Markdown解析需按块级到行内顺序逐层替换:先拆行处理标题、列表、引用等块元素,再统一处理加粗、斜体、链接等行内格式,注意避开代码块和HTML内容。

用正则实现 Markdown 解析,适合轻量场景(如评论框实时预览、简易文档渲染),不追求完整规范,重点是快、可读、易维护。
核心思路:逐行处理 + 优先级替换
Markdown 语法层级分明(标题 > 列表 > 段落 > 行内格式),正则替换需按顺序进行,避免嵌套干扰。推荐从块级元素开始,再处理行内元素(如加粗、链接)。
- 先用
split('\n')拆成行,逐行识别块类型(标题、列表、引用、代码块等) - 对每行应用对应正则,生成 HTML 片段
- 最后统一处理行内格式(如
**text**→<strong>text</strong>),注意避开代码块和 HTML 标签内容
常用块级语法的正则匹配示例
以下正则均使用 ^ 和 $ 锚定整行,配合 m 标志(multiline):
-
标题:
^#{1,6}\s+(.+)$→<h>$2</h>$1>(捕获组 1 是 # 数,2 是文本) -
无序列表:
^[*-]\s+(.+)$→<li>$1</li>(需后续包裹<ul>...</ul>) -
引用:
^>\s+(.+)$→<blockquote>$1</blockquote> -
代码块(单行):
^`([^`]+)`$→<code>$1;注意:三重反引号需单独处理(跨多行,建议用状态机或先提取再替换)
行内格式的安全替换技巧
行内语法(如 **bold**、[link](url))容易误匹配(如 URL 中的星号、邮件地址)。关键策略:
立即学习“Java免费学习笔记(深入)”;
- 先用
replace()处理「最外层」成对符号,避免嵌套干扰(如**a**b**c**应解析为<strong>a</strong>b<strong>c</strong>) - 加粗/斜体:用
(\*\*|__)(.*?)\1(\1确保前后一致),并加g和s标志(后者让.匹配换行) - 链接:
\[([^\]]+)\]\(([^)]+)\)→<a href="%242">$1</a>;注意括号需转义,且不匹配嵌套括号(Markdown 本身也不支持) - 替换前可先用占位符临时屏蔽代码块、HTML 片段,处理完再还原
简单但实用的整合结构
一个可直接运行的简化版函数:
function markdownToHtml(md) {
let lines = md.split('\n');
let htmlLines = [];
<p>for (let line of lines) {
// 块级处理(按优先级顺序)
if (/^#{1,6}\s/.test(line)) {
line = line.replace(/^(#{1,6})\s+(.+)$/, (<em>, hashes, text) =>
<code><h${hashes.length}>${text}</h${hashes.length}></code>
);
} else if (/^[<em>-]\s+/.test(line)) {
line = line.replace(/^[</em>-]\s+(.+)$/, (</em>, text) => <code><li>${text}</li></code>);
// 后续可合并连续 li 到 ul
} else if (/^>\s+/.test(line)) {
line = line.replace(/^>\s+(.+)$/, (_, text) => <code><blockquote>${text}</blockquote></code>);
} else if (/^``<code>/.test(line)) { // 简单跳过,或标记为代码块起始 line = '<pre class="brush:php;toolbar:false;"><code>'; } else if (line.trim() === '') { line = '<p> </p>'; // 空行转空段落 } else { line =</code><p>${line}</p>`;
}
htmlLines.push(line);
}</p><p>// 合并后统一处理行内格式
let joined = htmlLines.join('\n');
joined = joined
.replace(/**(.<em>?)**/g, (_, p1) => <code><strong>${p1}</strong></code>)
.replace(/*(.</em>?)*/g, (<em>, p1) => <code><em>${p1}</em></code>)
.replace(/[([^]]+)](([^)]+))/g, (</em>, text, url) =>
<code><a href="${url}">${text}</a></code>
);</p><p>return joined;
}</p>


















