Gitbook Mermaid插件正则匹配问题:无法识别带空格的代码块
排查Gitbook Mermaid插件正则修改后JS while循环阻塞问题
核心原因:正则灾难性回溯
你遇到的循环阻塞,几乎可以肯定是修改后的正则触发了灾难性回溯——正则引擎在匹配文本时,因为模糊匹配、嵌套重复的结构,陷入大量无效的分支尝试,导致CPU占用飙升、线程卡死。
原正则/^```mermaid((.*[\n]+)+?)?```$/im本身就有嵌套重复的问题((.*[\n]+)+?),如果修改时为了兼容空格,又加入了多个可选的空白匹配(比如\s*mermaid\s*),再结合.*这种无边界的模糊匹配,很容易让引擎在处理长文本时陷入无限回溯。
修复方案
1. 重构正则,避免回溯陷阱
改用排除型匹配+明确的空白处理,彻底避免嵌套重复和模糊匹配的问题:
// 支持```前后、与mermaid间任意空格的优化正则 const mermaidRegex = /```\s*mermaid\s*\n([\s\S]*?)\n```\s*/img;
\s*:匹配任意数量的空白字符(空格、换行、制表符),完美兼容各种空格场景[\s\S]*?:惰性匹配所有内容(包括换行),直到遇到下一行的```,避免过度匹配- 去掉原正则的嵌套重复结构,从根源上消除回溯风险
2. 调整循环写法,避免无限循环
如果是用来全局替换所有mermaid代码块,不要手动用while+exec,直接用JS原生的replace(带全局标志)更高效且安全:
// 全局替换所有匹配的代码块为SVG const processedContent = content.replace(mermaidRegex, (match, mermaidCode) => { // 这里替换成你的mermaid转SVG逻辑 return convertMermaidToSVG(mermaidCode); });
如果一定要用while循环,必须确保每次匹配后正确更新正则的lastIndex,且避免匹配空字符串:
const regex = /```\s*mermaid\s*\n([\s\S]*?)\n```\s*/img; let matchResult; while ((matchResult = regex.exec(content)) !== null) { const mermaidCode = matchResult[1]; // 替换当前匹配的代码块 content = content.replace(matchResult[0], convertMermaidToSVG(mermaidCode)); // 重置lastIndex,因为原字符串已被修改,避免匹配位置错乱 regex.lastIndex = 0; }
3. 验证正则的回溯风险
可以用regex101的调试功能查看匹配过程,如果出现大量"backtrack"记录,说明正则仍有优化空间。比如如果mermaid代码里不会出现```,可以把[\s\S]*?换成[^\n]*(\n[^\n]*)*,进一步缩小匹配范围。
内容的提问来源于stack exchange,提问作者flyingfox
相关产品推荐
相关产品推荐

