Search code examples
javascriptgreasemonkey

Changing text node contents globally in document


So I have this script that I'm using to change text node contents in JS. Irun this script in Greasemonkey:

(function() {
  var replacements, regex, key, textnodes, node, s; 

  replacements = { 

    "facebook": "channelnewsasia",
    "Teh": "The",
    "TEH": "THE",
    };

regex = {}; 
for (key in replacements) { 
    regex[key] = new RegExp(key, 'g'); 
} 

textnodes = document.evaluate( "//body//text()", document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null); 

for (var i = 0; i < textnodes.snapshotLength; i++) { 
    node = textnodes.snapshotItem(i); 
    s = node.data; 
    for (key in replacements) { 
        s = s.replace(regex[key], replacements[key]); 
    } 
    node.data = s; 
} 

})();

Which works really well.

Except my problem is, I'm trying to change value 0 to 75. However it is also changing other 0's on the page that are included in dates, like today's date.

Which is not what I want. I ONLY want it to change 0's that are by themselves. How do I go about this?

Thanks for any help.


Solution

  • Well, you'd need regular expression for that. Your script supports regexes, you just need to put it in the list of required replacements.

    Regular expression to match single zero would look like this: (?:[^0-9]|^)(0)(?:[^0-9]|$). It works by asserting that non-number must be before/after zero - or string beginning/end.

    You can put this into your list of replacements:

    replacements = { 
        "(?:[^0-9]|^)(0)(?:[^0-9]|$)": "75",
    };
    

    Alternativelly, if zeroes are always separated by space, use just this expression: \b0\b

    Notes to your code:

    • Remember that with your system, you must treat all replacement templates as regexes. So don't forget to escape characters like (, [ or . in replacements when you want to treat those characters literally.
    • Wrapping whole userscript in self invoking expression is unnecessary, userscript variable scope is already hidden from global scope.