4

I'm having some weird issues "improving" a bookmarklet. I took this example from here - it takes a regular expression and highlights text on the page matching the expression - I've reformatted it for easy reading using JSMin for Notepad++:

javascript : (function () {
var count = 0,
text,
regexp;
text = prompt("Search regexp:", "");
if (text == null || text.length == 0)
    return;
try {
    regexp = new RegExp("(" + text + ")", "i");
} catch (er) {
    alert("Unable to create regular expression using text '" + text + "'.\n\n" + er);
    return;
}
function searchWithinNode(node, re) {
    var pos,
    skip,
    spannode,
    middlebit,
    endbit,
    middleclone;
    skip = 0;
    if (node.nodeType == 3) {
        pos = node.data.search(re);
        if (pos >= 0) {
            spannode = document.createElement("SPAN");
            spannode.style.backgroundColor = "yellow";
            middlebit = node.splitText(pos);
            endbit = middlebit.splitText(RegExp.$1.length);
            middleclone = middlebit.cloneNode(true);
            spannode.appendChild(middleclone);
            middlebit.parentNode.replaceChild(spannode, middlebit);
            ++count;
            skip = 1;
        }
    } else if (node.nodeType == 1 && node.childNodes && node.tagName.toUpperCase() != "SCRIPT" && node.tagName.toUpperCase != "STYLE") {
        for (var child = 0; child < node.childNodes.length; ++child) {
            child = child + searchWithinNode(node.childNodes[child], re);
        }
    }
    return skip;
}
window.status = "Searching for " + regexp + "...";
searchWithinNode(document.body, regexp);
window.status = "Found " + count + " match" + (count == 1 ? "" : "es") + " for " + regexp + ".";})();

Here's my bespoke improvement to the first 10 lines for single-click highlighting for the :

javascript : (function () {
var count = 0,
regexp;
try {
    regexp = /\bwho\b|\bwhom\b|\blay\b|\blie\b|\bmoot\b|\bcontinual\b|\bcontinuous\b|\benvy\b|\bjealousy\b|\benvious\b|\bjealous\b|\bnor\b|\bmay\b|\bmight\b|\bwhether\b|\bfewer\b|\bless\b|\bdisinterested\b|\buninterested\b|\bdifferent than\b|\bimpactful\b|\baffect\b|\beffect\b|\birony\b|\bironic\b|\bnauseous\b/i;
} catch (er) {
    alert("Unable to create regular expression\n\n" + er);
    return;
}
...

The first works, the second doesn't. The first even works when copying the expression from the second into the prompt.

When the second runs, the browser consumes CPU for a while, then highlights squat. The first is near-instant. Behaviour doesn't seem to differ between IE9/Chrome17/FF10. Using new Regex(...) in the second doesn't help - I'm using the slash notation to save having to double slash the rest, making it less readable.

Would anyone be willing to point me towards my mistake?

Dan Caseley
  • 521
  • 6
  • 8
  • Not sure your regexp is valid. Try `/\b(who|whom| ... |nauseous)\b/i` (breaks on the outside, but - more importantly - parens around the branches) – Flambino Feb 14 '12 at 16:50

1 Answers1

1

you left out the "(" and ")" in your expression.

This works: regexp = /(\bwho\b|\bwhom\b|\blay\b|\blie\b|\bmoot\b|\bcontinual\b|\bcontinuous\b|\benvy\b|\bjealousy\b|\benvious\b|\bjealous\b|\bnor\b|\bmay\b|\bmight\b|\bwhether\b|\bfewer\b|\bless\b|\bdisinterested\b|\buninterested\b|\bdifferent than\b|\bimpactful\b|\baffect\b|\beffect\b|\birony\b|\bironic\b|\bnauseous\b)/i;

If you ask me why the parenthesis are necessary, I don't know. Related to code further downstream is my educated guess. All I did was compare what was different between the original code and your code; given the fact that the expression worked when entered into the input box.

DG.
  • 3,417
  • 2
  • 23
  • 28
  • 1
    A late addendum. I know why the parenthesis are necessary. You need parenthesis around the 'or' operators `|` like `(..|..|..|..)`. – DG. Mar 03 '12 at 04:49