What I’m trying to do is find all matches in a string, then wrap them in a styled span tag. The solution I’ve come up with uses recursion, here’s the code:
function foo(node, pattern) {
// alert(node.nodeValue);
// alert(node.nodeValue + '\n' + pattern.test(node.nodeValue));
if (pattern.test(node.nodeValue)) {
// alert(node.nodeValue);
var span = document.createElement('span');
var text = document.createTextNode(RegExp.rightContext);
span.className = 'someClass';
span.innerHTML = RegExp.$1;
node.nodeValue = RegExp.leftContext;
node.parentNode.insertBefore(span, node.nextSibling);
node.parentNode.insertBefore(text, span.nextSibling);
foo(text, pattern);
}
return;
}
See it in action at this fiddle: http://jsfiddle.net/Umcaf/
The issue I’m having is that it will not mark out all instances of the word ‘test’. If you play around with the alert statements, you will notice some odd behavior (it’s odd to me anyway). If you uncomment the very first alert, you will see all the correct strings I wish to test, but even though the very last string has the word ‘test’ in it, pattern.test(node.nodeValue) does not yield ‘true’. This is very perplexing.
Naturally I came up with the second alert statement. When the second alert statement is used, the it alerts incorrect strings (and by that I mean it doesn’t alert the very first full one and adds a last one that contains only white space) and the first occurrence of ‘test’ isn’t marked, but the last two are!
I’m fairly new to regular expressions but I thought I understood them well enough until now. Can anyone explain what is happening here?
Simply remove g from your regex, and the problem is gone.
You have a global match flag in your regex. It pushes the pointer forward each time you call test().
You can read more here:
https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/RegExp/test