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

时间:2019-09-16 06:09:52

标签: javascript regex reactjs string markdown

我没有使用dangerouslySetInnerHTML,而是尝试手动解析Markdown的一小部分并将其转换为React组件。我需要这样做是因为我有一些自定义组件,还需要在message字段中进行渲染,因此无论如何我都需要将它们变成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

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

快速 棕色狐狸

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

1 个答案:

答案 0 :(得分:0)

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

有关照明,请参见canonical answer

您可以编写正则表达式来解析 some 足够简单的Markdown / HTML,并且需要考虑诸如可能存在或可能不存在的空白,嵌套元素以及其他复杂性等问题您允许输入。没有解决的办法。

如果需要正确解析,请使用Markdown解析器。快速的Google会显示许多信息,例如:

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