Regular expressions and HTML don't mix very well。在您的情况下,如果您非常小心,您可以手动转义所有正确的值并生成有效的 HTML。如果您甚至有点粗心,您就会遇到格式错误或不安全的内容的问题。这并不是说“你绝对不能那样做”,但你至少应该意识到这样做所涉及的陷阱。
推荐的解决方案是永远不要自己以编程方式操作 HTML 字符串。相反,您应该操纵 HTMLElement objects 并信任您的 JavaScript 引擎来处理 HTML。
在您的情况下,我想说这个问题有两个组成部分。
一:将字符串转换为字符串的片段被标记为“应该突出显示”或“不应该突出显示”的表示形式。如果你引入如下接口(毕竟你使用了 TypeScript 标签):
interface HighlightableString {
value: string;
highlighted: boolean;
}
然后,带有突出显示部分的字符串可以表示为Array<HighlightableString>。
所以你需要一个函数来将"<some text>" 之类的字符串和"te" 之类的子字符串转换为类似
[
{value: "<some ", highlighted: false},
{value: "te", highlighted: true},
{value: "xt>", highlighted: false}
]
这是该功能的一种可能实现方式,但您可以按照自己的意愿进行操作。这是使用正则表达式的绝佳场所,因为这里无法表示“不安全”或“格式错误”的 HTML:
function highlightSubstring(s: string, substring: string): Array<HighlightableString> {
if (substring.length === 0) return [{ value: s, highlighted: false }]
const ret: Array<HighlightableString> = [];
for (
var prevPos = 0, pos = s.indexOf(substring);
pos >= 0;
prevPos = pos + substring.length, pos = s.indexOf(substring, prevPos)
) {
ret.push({ value: s.substring(prevPos, pos), highlighted: false });
ret.push({ value: substring, highlighted: true });
}
ret.push({ value: s.substring(prevPos), highlighted: false });
return ret;
}
两个:给定一个Array<HighlightableString>,一个父HTMLElement,以及一些突出显示文本的方式(例如,一个代表这种突出显示的HTMLElement),将正确突出显示的文本添加到该父元素。这是您根本不想使用正则表达式或 HTML 文本的地方。这是一种可能的实现方式:
function appendHighlightedString(
highlightableStrings: Array<HighlightableString>,
parentElement: HTMLElement,
highlightElement: HTMLElement
) {
highlightableStrings.forEach(hs => {
const textNode = document.createTextNode(hs.value);
if (hs.highlighted) {
const highlightClone = highlightElement.cloneNode(true);
highlightClone.appendChild(textNode)
parentElement.appendChild(highlightClone)
} else {
parentElement.appendChild(textNode);
}
})
}
注意该函数是如何使用Text 节点以及元素克隆和附加的。它从不直接查看 HTML。
好的,让我们看看它是否有效。我会试试<test content>的内容:
// make a highlight element
const highlightElement = document.createElement("span");
highlightElement.style.backgroundColor = '#FFFB00';
const wholeString = document.createElement("div"); // or whatever the parent element is
appendHighlightedString(
highlightSubstring("<test content>", "te"),
wholeString,
highlightElement
);
让我们看看它在 Firefox 中做了什么:
console.log(wholeString.innerHTML);
// <<span style="background-color: rgb(255, 251, 0);">te</span>st
// con<span style="background-color: rgb(255, 251, 0);">te</span>nt>
好吧,浏览器决定使用rgb(255, 251, 0) 而不是#FFFB00。但那是浏览器的特权;我们退出了 HTML 游戏。关键是如果您将该元素添加到文档中,
document.body.appendChild(wholeString);
它将以您想要的方式突出显示。
好的,希望对您有所帮助。祝你好运!