JavaScript全局Regex不是全局的



我正在尝试创建一个简单的扩展,用其他单词替换某些单词。我使用regexp查找全局匹配项,然后使用条件语句替换单词。然而,尽管我指定了"gi",它只替换了每个单词的第一个出现。有人能解释一下它为什么表现出这种行为吗?

我从这里得到了一些代码:Javascript Regex替换html属性中的文本NOT

代码如下:

Fiddle

// 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"]);

这是因为regex.exec方法从最后一个匹配的末尾开始返回"next"匹配。您正在做的是为您创建的每个RegExp对象获取第一个匹配项,进行替换,然后转到下一个RegExp目标。

对于每个RegExp对象,您需要再次运行regex,但要匹配最后一个节点结束的位置来启动它。使用您当前的代码,只需重新启动"g"开关即可。

最新更新