Markdown 的问题是语法风格十分松散,且方言众多。有很多行为在不同的实现上效果不一,例如下面几个问题:
1. 列表里可以定义标题吗?
2. 引言中定义的引用有效吗?
3. 用“*”开头的无序列表中插入以“*”组成的分割线,该生成一条分割线还是一个无序列表项?
所以,如果你是自己脑补语法,并且没有一个规范的测试集的,写起来会很痛苦,你会发现总有一些编辑器和你的实现的行为不一致。
现在常用的 Markdown 规范是 CommonMark [1],其提供了测试集,很多 Markdown 解析器实现都是基于此标准,楼主可以参考一下。
至于如何实现,用正则表达式问题也不大。无论怎么做,都要注意考虑安全问题和 corner case 。John Gruber 在 2004 年发文宣传 markdown 的时候附带了一个自己用 Perl 写的 markdown 到 HTML 的转译器,因为他没有考虑到 XSS 等问题被人所诟病 [2]。 另一个知名的 JavaScript 实现 marked,没有处理好嵌套列表,可以被特定输入触发栈溢出错误 [3]。
[1]:
https://spec.commonmark.org/[2]:
https://news.ycombinator.com/item?id=4700383[3]:
https://github.com/markedjs/marked/issues/1471