skip to Main Content

I have a problem with the javascript replace function and I don’t succeed to resolve it.

This is my code : https://jsfiddle.net/r36k20sa/1/

  var tags = ['zazie', 'johnny'];

  tags.forEach(function(element) {
    content = content.replace(
      new RegExp("(?!<a.*?>.*?)(\b" + element + "\b)(?!.*?<\/a>)", "igm"),
      '<a href="" class="esk-seo-plu-link" style="background:red;color:white">$1</a>'
    );
  });

In the tags array, if I reverse the array “johnny” then “zazie” all tags are well selected otherwise, some tags are missing. (The last in this example). What can be the trick?

What can be explained that ? It seems like the javascript replace function runs asynchronous?

Thanks for your help.

2

Answers


  1. Are you seriously using regex to process HTML when you have a DOM parser at your fingertips?

    var content = document.getElementById('content');
    
    function findTextNodes(root,ret) {
        // recursively descend into child nodes and return an array of text nodes
        var children = root.childNodes, l = children.length, i;
        ret = ret || [];
        for( i=0; i<l; i++) {
            if( children[i].nodeType == 1) { // ElementNode
                // excluding A tags here, you might also want to exclude BUTTON tags
                if( children[i].nodeName != "A") {
                    findTextNodes(children[i],ret);
                }
            }
            if( children[i].nodeType == 3) { // TextNode
                ret.push(children[i]);
            }
        }
        return ret;
    }
    var textNodes = findTextNodes(content);
    
    // now search those text node contents for matching tags.
    var tags = ['zazie','johnny'], tagcount = tags.length, regexes, tag;
    for( tag=0; tag<tagcount; tag++) {
        regexes[tag] = new RegExp("b"+tags[tag]+"b","i");
    }
    
    var node, match, index, tagtext, newnode;
    while(node = textNodes.shift()) {
        for( tag=0; tag<tagcount; tag++) {
            if( match = node.nodeValue.match(regexes[tag])) {
                index = match.index;
                textNodes.unshift(node.splitText(index + tags[tag].length));
                tagtext = node.splitText(index);
                newnode = document.createElement('a');
                newnode.href = "";
                newnode.className = "esk-seo-plu-link";
                newnode.style.cssText = "background:red;color:white";
                tagtext.parentNode.replaceChild(newnode,tagtext);
                newnode.appendChild(tagtext);
            }
        }
    }
    
    // and done - no more action needed since it was in-place.
    

    See it in action

    Login or Signup to reply.
  2. Please replace . with \.

      var tags = ['zazie', 'johnny'];
    
      tags.forEach(function(element) {
        content = content.replace(
          new RegExp("(?!<a.*?>\.*?)(\b" + element + "\b)(?!\.*?<\/a>)", "igm"),
          '<a href="" class="esk-seo-plu-link" style="background:red;color:white">$1</a>'
        );
      });
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search