来自https://github.com/iansinnott/react-string-replace/issues/33
的共享问题react-string-replace:https://github.com/iansinnott/react-string-replace
我无法使用reactStringReplace
格式化带粗体/斜体标签的文字。我把它设置如下:
var text1 = "[b]Testing bold [i]and italic[/i] tags[/b]"
var text2 = "[b]Testing bold [i]and italic tags[/b][/i]"
let replaced = reactStringReplace(text1, /\[b\]([\s\S]+)\[\/b\]/g, (match, i) => {
return <b key={i}>{match}</b>
})
replaced = reactStringReplace(replaced, /\[i\]([\s\S]+)\[\/i\]/g, (match, i) => {
return <i key={i}>{match}</i>
})
// result (html)
<b>Testing [i]bold and italic[/i] tags</b>
<b>Testing [i]bold and italic tags</b>[/i]
我不确定这是reactStringReplace
的问题,我正在使用正则表达式,还是其他什么。如果我首先应用斜体替换,我会得到斜体标签,我希望它们是,但[b]标签保持不变。这个用例是否可以使用reactStringReplace
,还是需要使用dangerouslySetInnerHtml
?
Bonus:reactStringReplace
是否能够处理不平衡的标签,或text2
中不正确格式化的标签,或者我应该进行一些预处理以确保字符串正确平衡和格式化?
答案 0 :(得分:1)
您的样本有多个问题,
<i key={match + i}>{match}</i>
(见下文)+
量词可能会匹配太多。;
等等。广告。 1:引用完整的example:
在许多React示例中,您会看到使用的
i
或index
变量 作为JSX标记的关键(例如本例中的<a>
标记),但在这种情况下,我们在三个独立的循环中进行迭代。 这意味着我们不能使用key={i}
因为所有三个JSX 标签可以获得相同的密钥。
广告。 2:然而,最重要的部分是你的匹配重叠,这与reactStringReplace
不相符。
示范:
const text = 'Hey @ian_sinn#reactconf';
let replacedText;
// Match @-mentions
replacedText = reactStringReplace(text, /@(\w+)/g, (match, i) => (
<b key={match + i}>@{match}</b>
));
// Match hashtags
replacedText = reactStringReplace(replacedText, /#(\w+)/g, (match, i) => (
<a key={match + i} href={`https://twitter.com/hashtag/${match}`}>#{match}</a>
));
我们在此示例中有不同的匹配:首先,@ian_sinn
匹配并替换,然后#reactconf
,因此替换按预期工作;但是,如果您使用\w
更改替换.
的第一个正则表达式,则会出现重叠匹配:现在,第二个替换将不会应用。
如果您避免重叠匹配,它会起作用:
render() {
const text = '[b]Testing bold [i]and italic[/i] tags[/b]';
let replacedText;
replacedText = reactStringReplace(text, /\[b\]((?:(?!\[\/b\]|\[i\]|\[\/i\]).)*)/g, (match, i) => (
<b key={match + i}>{match}</b>
));
replacedText = reactStringReplace(replacedText, /\[i\]((?:(?!\[\/b\]|\[i\]|\[\/i\]).)*)/g, (match, i) => (
<b><i key={match + i}>{match}</i></b>
));
replacedText = reactStringReplace(replacedText, /\[\/i\]((?:(?!\[\/b\]|\[i\]|\[\/i\]).)*)/g, (match, i) => (
<b key={match + i}>{match}</b>
));
replacedText = reactStringReplace(replacedText, /\[\/b\]((?:(?!\[\/b\]|\[i\]|\[\/i\]|$).)*)$/g, (match, i) => (
<b key={match + i}>{match}</b>
));
return (
<div>
{replacedText}
</div>
);
},
});
但是这需要你在这个问题上抛出更复杂的正则表达式,给你丑陋的标记,并且可以说,打败了整个冒险的目的......
广告。 3:使用不匹配的匹配将其与简单的香草正则表达替换进行比较:[\s\S]+?
const str = `[b]Testing bold [i]and italic[/i] tags[/b]`;
const result = str.replace(/\[b\]([\s\S]+?)\[\/b\]/gm, `<b>$1</b>`)
.replace(/\[i\]([\s\S]+?)\[\/i\]/gm, `<i>$1</i>`);
console.log('Substitution result: ', result);
判决:伤心,但现在official。截至目前,reactStringReplace不处理嵌套替换:
因为替换可以将数据类型更改为其他内容 字符串。如果你看这里你会看到它只运行替换 字符串。一旦你的第一次替换已经运行了元素 结果数组将是一个对象(即
<b>...</b>)
,因此没有替换 将在内部字符串上运行。