我没有使用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
因为没有空格分隔令牌。我希望该消息变成这样:
快速 棕色狐狸
我希望即使没有空格也能正常工作,并且不确定如何操作。此外,当前解决方案对于所有内容之前的空格似乎都很脆弱。有什么建议吗?
答案 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