0

I want to replace all matched text with another text, but I don't want replace if that text is in the alt or href attribute. Example:

<p>Hello world!</p>
<p><img src="hello.jpg" alt="Hello"/></p>
Hello

My code:

var replacepattern = new RegExp('Hello', 'gi');
newcontent = newcontent.replace(replacepattern, function(match, contents, offset, s) {
var link = 'demo.com'
    index++;
    if (link != '') {
        return '<a href="' + link + '">' + match + '</a>';
    } else {
        return match;
    }
});

It works perfect with text only. How can I match text except img src, alt etc?

Danny Beckett
  • 20,529
  • 24
  • 107
  • 134
Anh Tú
  • 636
  • 7
  • 21

1 Answers1

2

You can use jQuery itself to help you with the replacement:

$(html)
    .contents()
    .filter(function() {
        return this.nodeType == 1 || this.nodeType == 3;
    }).each(function() {
        this.textContent = this.textContent.replace(replacepattern, 'whatever');
    });

Note that the last occurrence of Hello is not replaced, because it's technically invalid to have a text node as a child of <body>.

Also, you would have to modify it to work in IE < 9 or 10; basically the browser is expected to support node.textContent :)

Update

The problem was slightly more complicated; or maybe my mind is making it more difficult than it is. Replacing text nodes with jQuery ain't the easiest to do, so some pure JS is required for that:

$('<div><p>Hello world!</p><p><img src="hello.jpg" alt="Hello"/></p>Hello</div>')
  .find('*')
  .andSelf()
  .each(function() {
    for (var i = 0, nodes = this.childNodes, n = nodes.length; i < n; ++i) {
      if (nodes[i].nodeType == 3) {
        var txt = nodes[i].textContent || nodes[i].innerText,
            newtxt = txt.replace(/Hello/g, 'Bye');
        if (txt != newtxt) {
          var txtnode = document.createTextNode(newtxt);
          this.replaceChild(txtnode, nodes[i]);
        }
      }
    }
})
  .end()
  .end()
  .appendTo('body');
Ja͢ck
  • 170,779
  • 38
  • 263
  • 309
  • Thanks Jack, i tried your code, but after replace, img tag has been removed. Any idea? – Anh Tú Mar 28 '13 at 18:00
  • try add a div wrapper like this: `

    Hello world!

    Hello

    Hello`
    i think problem occured when node not in the same level.
    – Anh Tú Mar 29 '13 at 02:24
  • thanks @Jack so much! i found a solution by using this regex: `new RegExp('hello(?![^<]*>)',"gi")` But your way is a good one. – Anh Tú Mar 30 '13 at 04:59