
本文详解如何用 JavaScript 正则表达式精准识别并替换含前后空格的 Mermaid 代码块(如 mermaid 或mermaid),修复原 GitBook 插件因正则过于严格导致的解析失败问题。
本文详解如何用 javascript 正则表达式精准识别并替换含前后空格的 mermaid 代码块(如 ``` mermaid 或 ```mermaid),修复原 gitbook 插件因正则过于严格导致的解析失败问题。
在使用 gitbook-plugin-mermaid-gb3 时,原始正则 /^```mermaid((.*[ ]+)+?)?```$/im 存在明显局限:它要求代码块起始标记必须严格为 ```mermaid(零空格),无法匹配常见的变体,例如:
- ✅ ``` mermaid(开头有空格/制表符,mermaid 前后有空白)
- ✅ ```mermaid(行首缩进)
- ❌ abc```mermaid(前缀非空白字符)
- ❌ ```mermaid abc(mermaid 后带非法内容)
这类限制导致大量合法 Markdown 代码块被跳过,Mermaid 图表无法渲染。
✅ 推荐正则方案(兼顾鲁棒性与可读性)
const mermaidRegex = /^[ ]*```s*mermaids*$(?: ? | )([^`]*(?:`[^`]+)*)```$/igm;
? 关键改进说明:
Telegram Markdown Adapter下载将 Markdown 格式的回复转换为适合 Telegram 的富文本,避免渲染错误。适用于用户偏好 Markdown 但目标平台为 Telegram 的场景。
- ^[ ]*:匹配行首任意数量空格或制表符(支持缩进);
- s*mermaids*:允许 mermaid 前后存在任意空白(空格、换行、制表符);
- $ + (?: ? | ):显式匹配换行符(兼容 Windows/Linux/macOS),避免 ^$ 在多行模式下误判;
- ([^](?:[^]+)):**安全捕获代码内容**——通过“非反引号字符 + 可选单个反引号+非反引号”组合,精准提取代码块主体,规避.*` 的贪婪匹配风险(防止跨块误吞);
- igm 标志:i(忽略大小写)、g(全局替换)、m(多行模式,使 ^/$ 匹配每行起止)。
✅ 替换逻辑重构(简洁可靠)
原插件采用 exec() 循环 + replace() 逐次处理,易因正则状态重置出错;推荐改用单次全局 String.prototype.replace():
function processMermaidBlockList(page) {
page.content = page.content.replace(
mermaidRegex,
'<div class="mermaid">$1</div>'
);
return page;
}
✅ $1 自动引用正则中第一个捕获组(即 Mermaid 代码内容),无需手动解析 match[1];
✅ 全局替换天然避免循环陷阱,性能更优,逻辑更清晰。
⚠️ 注意事项与最佳实践
- *避免 `.跨行贪婪匹配**:原始正则中(.)在多行场景下可能意外吞掉后续代码块。新正则使用[^`]` 显式限定边界,确保只捕获当前块内内容;
- 换行符兼容性:明确使用 (?: ? | ) 替代 [ ]+,防止因行尾符差异导致匹配失败;
- 测试验证建议:在 regex101.com 中启用 g 和 m 标志,并粘贴完整 Markdown 文本进行多块匹配验证;
- 插件集成提示:若修改 index.js,需确保正则字面量中反斜杠未被 JS 字符串转义(如 s 应写作 \s),但此处使用 /.../ 语法,无需额外转义。
✅ 总结
通过升级正则为 ^[ ]*```s*mermaids*$(?: ? | )([^](?:[^]+))``$/igm 并改用 replace() 全局替换,即可稳健支持所有合规 Mermaid 代码块格式(含空格、缩进、跨平台换行),彻底解决 GitBook 插件解析失效问题。该方案兼顾准确性、可维护性与执行效率,是 Markdown 代码块解析的典型优化范例。











