写一个 markdown 解析器,用什么方式比较好呢?

2020-06-16 14:41:56 +08:00
 SpiritLingPub
  1. 正则表达式匹配处理
  2. 使用栈的方式处理。一层一层解析
  3. ......欢迎补充
2792 次点击
所在节点    JavaScript
7 条回复
wednesdayco
2020-06-16 15:00:11 +08:00
基本上就是正则了……
leishi1313
2020-06-16 15:14:29 +08:00
正。。正则写 parser ?学点函数式,你会发现写 parser 爽一笔
imdong
2020-06-16 15:39:01 +08:00
前几天还真就尝试用正则表达式去写这玩意...

https://regex101.com/r/3pnVNg/1/
zarte
2020-06-16 16:44:37 +08:00
不是已经有现成的了么
Death
2020-06-16 16:59:28 +08:00
@leishi1313
他这不是 recursive descent parser 的思路吗?
正则来做 lexing 也没啥问题吧
ruyu
2020-06-17 10:38:11 +08:00
正则解析语法太难受了, 用 [PEG]( https://bford.info/packrat/) 吧.
chengluyu
2020-06-17 22:00:01 +08:00
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

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/682051

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX