我试图解析一些文字,以便_this is emphasized!_
包含在<em>
标记中,如下所示:<em>this is emphasized!</em>
。
我的组件目前看起来像这样:
export default class TextParser extends React.Component {
render() {
let text = this.props.text,
parsed, regex, paragraphs;
regex = {
paragraph: /(?:\r\n){2,}/g,
emphasize: /\_(.*?)\_/g,
strong: /\*(.*?)\*/g,
}
// Apply regex
text = text.replace(regex.emphasize, (str) => {
let parsed = str.substr(1, str.length - 1);
return ('<em>' + parsed + '</em>')
})
paragraphs = text.split(regex.paragraph) || []
paragraphs = paragraphs.map((text, i) => {
return (
<p key={i}>
{text}
</p>
)
})
return (
<div className="document">{paragraphs}</div>
)
}
}
这不起作用,但输出html以纯文本显示标签,而不是在html中使用它们。这当然是因为消毒。
我可以dangerouslySetInnerHTML
但我想避免这种情况。如何使用<em>
标记替换文本之间的下划线?
答案 0 :(得分:2)
正如您所注意到的那样,将字符串"<em>"
作为replace
结果的一部分,只会添加该字符串而不是实际标记。
您无法直接在replace
内创建标记,因为它在字符串上运行。
相反,将字符串分解为单独的元素,并将标记添加到您需要的位置。你已经在段落案例中做了类似的事情。
因为段落大小写也适用于字符串,所以这些操作只能嵌套,因为一旦完成操作,就不再有纯文本字符串,而是有一个对象数组。所以在这个例子中,我在段解析中移动了<em>
解析。
最后一点,我必须修改emphasize
的正则表达式,以便它捕获下划线,因为我需要在完成拆分后再次检查它是否匹配。
let text = this.props.text,
parsed, regex, paragraphs;
regex = {
paragraph: /(?:\r\n){2,}/g,
emphasize: /(\_.*?\_)/g,
strong: /\*(.*?)\*/g,
}
paragraphs = text.split(regex.paragraph) || []
paragraphs = paragraphs.map((text, i) => {
return (
<p key={i}>
{
// Apply regex
text.split(regex.emphasize).map((str) => {
let parsed = str.search(regex.emphasize) !== -1
? (<em>{str.substr(1, str.length - 2)}</em>)
: str;
return parsed;
})}
</p>
)
})
return (
<div className="document">{paragraphs}</div>
)
根据您在下面的评论,您还想知道如何处理/或格式化案例。所以为了完整性,我在这里包含了代码。我选择将格式化模式合并为一个正则表达式,然后我明确检查“_”或“*”以决定是添加em
还是b
标记。然后我会在匹配时递归调用它,以防其中有其他匹配。您可以选择以不同的方式清理它,但我希望这会有所帮助。
let text = this.props.text,
parsed, regex, paragraphs;
regex = {
paragraph: /(?:\r\n){2,}/g,
formatting: /(\_.*?\_)|(\*.*?\*)/g,
}
let applyFormatting = (text) => {
return text.split(regex.formatting).filter(n => n).map((str) => {
let parsed = str[0] == '_'
? (<em>{applyFormatting(str.substr(1, str.length - 2))}</em>)
: str[0] == '*'
? (<b>{applyFormatting(str.substr(1, str.length - 2))}</b>)
: str;
return parsed;
});
};
paragraphs = text.split(regex.paragraph) || []
paragraphs = paragraphs.map((text, i) => {
return (
<p key={i}>
{ applyFormatting(text) }
</p>
)
})
return (
<div className="document">{paragraphs}</div>
)