在JS的replaceAll操作中忽略给定字符串中的html标签(特别是标签)



我的情况下,我通过URL数组(例如[www.stackoverflow.com, www.ex.com])和匹配这些URL一个接一个与给定的字符串在循环和替换锚标记,使其可点击。

我能够使用JSreplaceAll方法做到这一点,但在给定字符串中多次出现相同url的情况下,它甚至匹配标签中的url。

例如,如果给定字符串为"Check it out at www.stack.com/abc and bookmark the www.stack.com, www.overflow.com",给定URL数组为[www.stack.com/abc, www.stack.com]

在第一次替换迭代中,它将是"Check it out at <a href="www.stack.com/abc">www.stack.com/abc</a> and bookmark the www.stack.com"

然后问题发生在第二次迭代,它甚至将替换字符串的标签。我想在replaceAll方法期间忽略html标记。有人能帮我一下吗?

我试图忽略标签与下面的正则表达式,但它不工作的内容之间的锚标记。

exString.replaceAll(new RegExp(url + "(?![^<>]*>)", "gi"), replaceText);

让我们将它们分开并连接

const div = document.getElementById("text");
let str = div.textContent;
let arr = str.split(/ /)
console.log(arr)
const urls = ["www.stack.com/abc", "www.stack.com"];
arr.forEach((word,i) => {
const punctuation = word.match(/(W$)/)
if (punctuation) word = word.slice(0,-1)
const idx = urls.indexOf(word);
if (idx !=-1) arr[i] = arr[i].replace(word,`<a href="${word}">${word}</a>`)
})
console.log(arr)
div.innerHTML = arr.join(" ")
<div id="text">Check it out at www.stack.com/abc and bookmark the www.stack.com, www.overflow.com.</div>

虽然mplungjan提供的解决方案很聪明,而且效果很好,但我想发布一个替代方案。

来自可接受答案的算法将输入字符串处理成一个单词数组,然后继续遍历每个URL上的每个单词。然后,它需要查看是否有任何单词以符号结尾,并截断。这将有点消耗,因为可以想象50个单词X 5个可能的url = 250个组合和O(n^2)的计算。然后想象有20个可能的url和20个输入文本,每个文本包含15个以上的单词。最后,要提一下这个算法可能有区分大小写的问题。

这个解决方案从mplungjan的方法中使用了很多想法,但是相反,它只会通过RegEx快速缩小实际需要处理的内容,然后再次循环应用实际匹配的内容。另外,RegEx纠正了可能的大小写敏感问题。

let str = 'Check it out at www.stack.com/abc and bookmark the www.stack.com, www.overflow.com.';
let urls = ["www.stack.com", "www.stack.com/abc", "www.not-here.com"];
let arReplace = [];
// sort by longest URLs (prevents processing identical root domains on sub-domains)
urls = urls.sort((a, b) =>{
if(b.length > a.length)
return 1
return -1
});
// find URLs and apply replacement tokens
urls.forEach((url) => {
if(str.match(new RegExp('\b' + url + '\b', 'i'))){
arReplace.push(url);
str = str.replace(new RegExp('\b' + url + '\b', 'gi'), '%ZZ' + (arReplace.length - 1) + 'ZZ%')
}
});
// replace tokens
arReplace.forEach((url, n)  =>{
str = str.replace(new RegExp('%ZZ' + n + 'ZZ%', 'g'), '<a href="' + url + '">' + url + '</a>')
});
document.body.innerHTML = str

小提琴链接:https://jsfiddle.net/e05o9cra/

最新更新