【发布时间】:2014-10-26 07:33:56
【问题描述】:
我正在尝试创建一个简单的扩展,将某些单词替换为其他单词。我正在使用正则表达式来查找全局匹配,然后使用条件来替换单词。但是,尽管我指定了“gi”,但它只替换了每个单词的第一次出现。谁能解释它为什么表现出这种行为?
我从这里得到了一些代码:Javascript Regex to replace text NOT in html attributes
代码如下:
// Reusable generic function
function surroundInElement(el, regex, surrounderCreateFunc) {
// script and style elements are left alone
if (!/^(script|style)$/.test(el.tagName)) {
var child = el.lastChild;
while (child) {
if (child.nodeType == 1) {
surroundInElement(child, regex, surrounderCreateFunc);
} else if (child.nodeType == 3) {
surroundMatchingText(child, regex, surrounderCreateFunc);
}
child = child.previousSibling;
}
}
}
// Reusable generic function
function surroundMatchingText(textNode, regex, surrounderCreateFunc) {
var parent = textNode.parentNode;
var result, surroundingNode, matchedTextNode, matchLength, matchedText;
while ( textNode && (result = regex.exec(textNode.data)) ) {
matchedTextNode = textNode.splitText(result.index);
matchedText = result[0];
matchLength = matchedText.length;
textNode = (matchedTextNode.length > matchLength) ?
matchedTextNode.splitText(matchLength) : null;
surroundingNode = surrounderCreateFunc(matchedTextNode.cloneNode(true));
parent.insertBefore(surroundingNode, matchedTextNode);
parent.removeChild(matchedTextNode);
}
}
// This function does the surrounding for every matched piece of text
// and can be customized to do what you like
function createSpan(matchedTextNode) {
var val = matchedTextNode.nodeValue;
var valuelower = val.toLowerCase();
if(valuelower === "nice" || valuelower === "good" || valuelower === "great" || valuelower === "awesome" || valuelower === "amazing"){
var t = document.createTextNode("gj");
var el = document.createElement("span");
el.style.color = "red";
el.appendChild(t);
return el;
}
if(valuelower === "bad" || valuelower === "terrible" || valuelower === "horrendous" || valuelower === "awful" || valuelower === "abominable"){
var t = document.createTextNode("bj");
var el = document.createElement("span");
el.style.color = "red";
el.appendChild(t);
return el;
}
if(valuelower === "does"){
var t = document.createTextNode("dose");
var el = document.createElement("span");
el.style.color = "red";
el.appendChild(t);
return el;
}
}
// The main function
function wrapWords(container, words) {
// Replace the words one at a time.
for (var i = 0, len = words.length; i < len; ++i) {
surroundInElement(container, new RegExp(words[i], "gi"), createSpan);
}
}
wrapWords(document.body, ["nice", "good", "great", "awesome", "amazing", "bad", "terrible", "horrendous", "awful", "abominable", "does"]);
【问题讨论】:
-
忽略详细问题。你能解释一下代码背后的整体想法吗?我了解您想替换页面上的单词。但您是指在特定元素、整个页面等中吗?
-
删除“g”它将解决您的问题。正则表达式有点损坏(行为怪异) - 正则表达式也不会被重置 - 所以在每次连续执行时,它都会从最后一个匹配索引继续 - 尝试 xregexp.com 代替
-
@SReject,代码的目的是解析 DOM 树,只更改可见的单词,而不是隐藏 HTML div 等中的单词。 Dinesh,效果很好。谢谢!
标签: javascript regex dom