如何将 Markdown 变成一系列 React 组件?



我没有使用dangerouslySetInnerHTML,而是尝试手动解析Markdown的一小部分并将它们转换为React组件。我需要这样做,因为我有一些自定义组件,我也需要在消息字段中渲染,所以我无论如何都需要将它们转换为 React 组件。此外,它避免了XSS攻击的可能性。

我最初的想法只是在空间上拆分消息,并有条件地将每个令牌转换为 React 组件,类似于这样:

matchMarkdown(part) {
let match = part.match(/(^|[^\])(*)(.*)(*)/g); // match on *asdf* but not *asdf*
if (match !== null) {
return <strong> {match[3]}</strong>;
}
match = part.match(/(^|[^\])(_)(.*)(_)/); // match on _qwer_ but not _qwer_
if (match !== null) {
return <em> {match[3]}</em>;
}
return " " + part;
}
convertMarkdownToComponents() {
let parts = this.state.body.split(" ");
return (
<div>
{parts.map(this.matchMarkdown)}
</div>
);
}

几乎有效,除了它仅在空间上分裂的问题。例如,它将处理以下消息:

the _quick_ *brown* fox

但不在此消息上:

the _quick_*brown* fox

因为没有分隔令牌的空间。我希望这条消息变成这样:

快速的棕色狐狸

我希望即使没有空格也能让它工作,但不确定如何工作。此外,当前的解决方案对于所有内容之前的空间似乎非常脆弱。有什么建议吗?

使用正则表达式解析 Markdown 永远不会有趣或完整,因为您无法使用正则表达式解析任意 Markdown。出于同样的原因,您无法使用正则表达式解析任意 HTML。

请参阅此规范答案以获取照明。

你可以编写一个正则表达式来解析一些足够简单的 Markdown/HTML,并且您需要考虑可能存在或不存在的空格、嵌套元素以及输入中允许的其他复杂性。这是无法回避的。

如果您需要正确解析 Markdown 解析器,请使用它。快速谷歌显示许多,例如:


https://github.com/evilstreak/markdown-js https://github.com/markedjs/marked
https://github.com/showdownjs/showdown

最新更新