Javascript Regexp - match string template if string inside specified tag

Am I trying to replace all occurrences of some.text.and.dots ??? on the html page to add a link to it. I created this regex that does this:

\? \? \? ([A-z0-9.] *) \? \? \?

However, I would like to exclude any result that is inside the link: "<a ...> ... MY PATTERN ... </a>", and I am a bit stuck as to how to do this, all my attempts failed on this moment.

+3
source share
2 answers

It’s not clear what kind of "HTML" you are working on. If this is HTML code, possibly something from an Ajax request, then you can use a regex; matching both the link and the template, and then figure out what to do in the callback:

var html = document.body.innerHTML; html = html.replace(/(<a\s.*?>.*?<\/a>)|(\?\?\?([a-z0-9.]*)\?\?\?)/g, function ( a, b, c, d ) { return ( a[0] == '<' ) ? a : '<a href="#">' + d + '</a>'; }); context.innerHTML = html; 

Conveniently, replace() can use the callback function as a replaceable generator, rather than a simple string.

If you are working on a live DOM tree, you might want to respect events on the nodes, not just reset innerHTML . To do this, you will need a more primitive approach:

 // returns all childnodes of type text that do not have A as parent function walker ( node ) { var nodes = []; for (var c, i = 0; c = node.childNodes[i]; i++) { if ( c.nodeType === 1 && c.tagName !== 'A' ) { nodes = nodes.concat( arguments.callee( c ) ); } else if ( c.nodeType === 3 ) { nodes.push( c ); } } return nodes; } var textNodes = walker( document.body ); for (var i = 0; i < textNodes.length; i++) { // create an array of strings separating the pattern var m = textNodes[i].nodeValue.split( /(\?\?\?([a-z0-9.]*)\?\?\?)/ ); if ( m.length > 1 ) { for (var j=0; j<m.length; j++) { var t, parent = textNodes[i].parentNode; // create a link for any occurence of the pattern if ( /^\?\?\?([a-z0-9.]*)\?\?\?$/.test( m[j] ) ) { var a = document.createElement( 'a' ); a.href = "#"; a.innerHTML = RegExp.$1; // m[j] if you don't want to crop the ???'s parent.insertBefore( a, textNodes[i] ); t = document.createTextNode( ' ' ); // whitespace padding } else { t = document.createTextNode( m[j] ); } parent.insertBefore( t, textNodes[i] ); } // remove original text node parent.removeChild( textNodes[i] ); } } 

This method applies only to text fields, and then only those that match the pattern.

+9
source

JavaScript does not inherently support appearance. To do this, you need to run .match (), and then for each of your matches you will need to make matches in your tags (for example, / <a \ s +. *?> / Immediately before your match, and then after </a> after your satisfaction).

Good luck

0
source

All Articles