我需要编写第二个RegExp来查找d
内不在标签中的变量sentence
。因此应跳过标签中的变量。
正则表达式'(?:^|\\b)('+d+')(?=\\b|$)'
会找到d变量但我需要用<span>
排除class="description"
标记。
新句子包含在新标签中。
sentence = "This is some word. <span class='description'>word</span> in tag should be skipped"
d = 'word'
re = new RegExp('(?:^|\\b)('+d+')(?=\\b|$)', 'gi')
sentence = sentence.replace(re, "<span>$1</span>")
我想要实现的结果是:
"This is some <span>word</span>. <span class='description'>word</span> in tag should be skipped"
我正在使用coffeescript,感谢您的帮助。
答案 0 :(得分:0)
试试这个:(word)(?![^<>]*<\/)
完整代码:
var sentence = "This is some word. <span class='description'>word</span> in tag should be skipped"
var d = 'word'
var re = new RegExp('('+d+')(?![^<>]*<\/)', 'gi')
sentence = sentence.replace(re, "<span>$1</span>")
我的回答基于以下代码段:https://regex101.com/library/gN4vI6
答案 1 :(得分:0)
尝试使用正则表达式操作HTML并不是一个好主意:迟早会遇到失败的边界条件。也许某些<
或>
出现在属性值内部,甚至出现在文本节点内,而搜索到的术语也可能出现在意外的位置,例如HTML注释,属性值或脚本标记,......边界案例列表很长。
此外,您的搜索字词可能包含在正则表达式语法中具有特殊含义的字符,因此您至少应该逃避这些字符。
这是一个解决方案,使用DOM功能将字符串解释为HTML,并且只替换文本节点中的文本:
function escapeRegExp(str) {
return str.replace(/[\[\]\/{}()*+?.\\^$|-]/g, "\\$&");
}
function wrapText(sentence, word) {
const re = new RegExp("\\b(" + escapeRegExp(word) + ")\\b", "gi"),
span = document.createElement('span');
span.innerHTML = sentence;
Array.from(span.childNodes, function (node) {
if (node.nodeType !== 3) return;
node.nodeValue.split(re).forEach(function (part, i) {
let add;
if (i%2) {
add = document.createElement('span');
add.textContent = part;
add.className = 'someClass';
} else {
add = document.createTextNode(part);
}
span.insertBefore(add, node);
});
span.removeChild(node);
});
return span.innerHTML;
}
const html = 'This is some word. <span class="word">word</span> should stay',
result = wrapText(html, 'word');
console.log(result);
在评论中,您提到您现在还希望在某些标记内进行替换,例如p
。
我假设您希望所有元素都发生这种情况,除了具有特定类别的元素,例如您用于包装span
元素的类,但您当然可以根据需要自定义条件(例如仅递归到p
或...)。
代码只需要进行一些修改:
function escapeRegExp(str) {
return str.replace(/[\[\]\/{}()*+?.\\^$|-]/g, "\\$&");
}
function wrapText(sentence, word) {
const re = new RegExp("\\b(" + escapeRegExp(word) + ")\\b", "gi"),
doc = document.createElement('span');
doc.innerHTML = sentence;
(function recurse(elem) {
Array.from(elem.childNodes, function (node) {
// Customise this condition as needed:
if (node.classList && !node.classList.contains('someClass')) recurse(node);
if (node.nodeType !== 3) return;
node.nodeValue.split(re).forEach(function (part, i) {
let add;
if (i%2) {
add = document.createElement('span');
add.textContent = part;
add.className = 'someClass';
} else {
add = document.createTextNode(part);
}
elem.insertBefore(add, node);
});
elem.removeChild(node);
});
})(doc);
return doc.innerHTML;
}
const html = '<p><b>Some word</b></p>. <span class="someClass">word</span> should stay',
result = wrapText(html, 'word');
console.log(result);