Page 2 of 2 FirstFirst 12
Results 11 to 17 of 17

Thread: multi-browser javascript word replace

  1. #11
    Join Date
    Mar 2005
    Location
    SE PA USA
    Posts
    30,495
    Thanks
    82
    Thanked 3,449 Times in 3,410 Posts
    Blog Entries
    12

    Default

    That can really be worked out a number of ways depending upon how you want your document affected, here's one way (case insensitive, whole words):

    Code:
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
       "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <title></title>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
    <script type="text/javascript">
    function toBold(str){
    str = str || document.getElementById('whatstring').value;
    var r = new RegExp('(\\b' + str + '\\b)', 'gi'),
    bb = function(a,b){return b.bold()},
    wa = document.getElementById('workarea');
    wa.innerHTML = wa.innerHTML.replace(r, bb);
    }
    function toNorm(str){
    str = str || document.getElementById('whatstring').value;
    var r = new RegExp('(<b>)+( *)(' + str + ')( *)(<\\/b>)+', 'gi'),
    nn = function(a,b,c,d,e){return c + d + e;},
    wa = document.getElementById('workarea');
    wa.innerHTML = wa.innerHTML.replace(r, nn);
    }
    </script>
    </head>
    <body>
    <div id="workarea">
    <b>This </b> is an example with other examples for this.
    </div>
    <div>
    <input type="text" id="whatstring"><br>
    <input onclick="toBold()" type="button" value="Bold">
    <input onclick="toNorm()" type="button" value="Normal">
    </div>
    </body>
    </html>
    - John
    ________________________

    Show Additional Thanks: International Rescue Committee - Donate or: The Ocean Conservancy - Donate or: PayPal - Donate

  2. #12
    Join Date
    Sep 2010
    Posts
    6
    Thanks
    5
    Thanked 0 Times in 0 Posts

    Default whole words

    Hi John – how would you implement \b (whole word) in your first example?

    thanks as always!

    Quote Originally Posted by jscheuer1 View Post
    Code:
    regex[key] = new RegExp(key, 'g');

  3. #13
    Join Date
    Mar 2005
    Location
    SE PA USA
    Posts
    30,495
    Thanks
    82
    Thanked 3,449 Times in 3,410 Posts
    Blog Entries
    12

    Default

    Well, \b doesn't mean 'whole word'. It means 'word boundary'. That is it represents any character that cannot be a part of a word.

    In a new RegExp constructor, the \ must be escaped - I think it's twice, so you would have (you haven't specified how you want to use the \b) something like:

    Code:
    regex[key] = new RegExp('\\\b' + key, 'g');
    If you want more help:

    Please post a link to a page on your site that contains the problematic code so we can check it out.
    - John
    ________________________

    Show Additional Thanks: International Rescue Committee - Donate or: The Ocean Conservancy - Donate or: PayPal - Donate

  4. The Following User Says Thank You to jscheuer1 For This Useful Post:

    bfinoradin (11-29-2010)

  5. #14
    Join Date
    Sep 2010
    Posts
    6
    Thanks
    5
    Thanked 0 Times in 0 Posts

    Default

    Ah, I see. The problem I am having is (for instance) if I want to replace "a", currently the script will replace the "a" within "about", or if I chose to replace the word "locate" it will affect "relocate" as well. For my application of the script it would ideally replace words only as typed, albeit case insensitive.

    As you can see here it is currently removing all occurrences of "a".

    Here is what I am using:
    Code:
    if (document.documentElement && document.documentElement.childNodes)
    window.onload = function() {
    var tn = [], grabTextNodes = function(n) {
    for (var i = n.length - 1; i > -1; --i)
    if (n[i].nodeName != '#text' && n[i].childNodes)
    grabTextNodes(n[i].childNodes);
    else
    tn[tn.length] = n[i];
    }, replacements = {
    
        
        'a'     : "_",
        
        
        }, regex = {};
    
    grabTextNodes(document.body.childNodes);
    
    for (var key in replacements) {
    regex[key] = new RegExp(key, 'g');
    for (var i = tn.length - 1; i > -1; --i)
    tn[i].nodeValue = tn[i].nodeValue.replace(regex[key], replacements[key]);
    };
    };

  6. #15
    Join Date
    Mar 2005
    Location
    SE PA USA
    Posts
    30,495
    Thanks
    82
    Thanked 3,449 Times in 3,410 Posts
    Blog Entries
    12

    Default

    Some things you might like to correct - On fox.php the style section comes before the opening <HTML> tag. It should be external and come in the head section. On the same page the script tag comes after the closing </HTML> tag. It should come before the closing </BODY> tag.

    On to the script. No comma allowed after the last entry in an Object. This affects only IE and some older browsers as far as I know. Most if not all other modern browsers now error correct for this:

    Code:
    replacements = {
    
        
        'a'     : "_",
        
        
        }
    That's only one entry. If you had more than one:

    Code:
    replacements = {
    
        
        'a'     : "_",
        'b'     : "+"
        
        }
    OK, I tried this out, it needs to be escaped only once:

    Code:
    if (document.documentElement && document.documentElement.childNodes)
    window.onload = function() {
    var tn = [], grabTextNodes = function(n) {
    for (var i = n.length - 1; i > -1; --i)
    if (n[i].nodeName != '#text' && n[i].childNodes)
    grabTextNodes(n[i].childNodes);
    else
    tn[tn.length] = n[i];
    }, replacements = {
    
        
        'a'     : "_"
        
        
        }, regex = {};
    
    grabTextNodes(document.body.childNodes);
    
    for (var key in replacements) {
    regex[key] = new RegExp('\\b' + key + '\\b', 'g');
    for (var i = tn.length - 1; i > -1; --i)
    tn[i].nodeValue = tn[i].nodeValue.replace(regex[key], replacements[key]);
    };
    };
    - John
    ________________________

    Show Additional Thanks: International Rescue Committee - Donate or: The Ocean Conservancy - Donate or: PayPal - Donate

  7. The Following User Says Thank You to jscheuer1 For This Useful Post:

    bfinoradin (11-29-2010)

  8. #16
    Join Date
    Sep 2010
    Posts
    6
    Thanks
    5
    Thanked 0 Times in 0 Posts

    Lightbulb

    Awesome – thanks John, a huge help as usual.

    One more question for you… I think this would fundamentally change the structure of the script, but how would I implement replacement where it is replacing each character of filtered words individually, as the have done here. In other words… I define "*" as the replacement, and "this gets filtered" would become "**** **** ********".

  9. #17
    Join Date
    Mar 2005
    Location
    SE PA USA
    Posts
    30,495
    Thanks
    82
    Thanked 3,449 Times in 3,410 Posts
    Blog Entries
    12

    Default

    Well, you don't want to have the bad words one place and then see them *'ed out in another place as that example code offers to do. But its method can be incorporated. However, its method isn't supported in some legacy browsers and I'm not sure how to test for and recover from that, or if it's even worth bothering to. It's fine in IE 5.5+ and virtually any other browsers' "version 5+" (that includes any browser written after Netscape 5 (like Firefox - all versions, Safari - all versions) hit the scene many, many years ago).

    I also notice that you seem willing to insert this script at the end of the page, in which case we can gain both significant speed up and potential flexibility in the use of other scripts for the pages that use this script by using an anonymous function rather than the window.onload:

    Code:
    if (document.documentElement && document.documentElement.childNodes)
    (function(){ // anonymous function instead of onload
    var tn = [], grabTextNodes = function(n) {
    for (var i = n.length - 1; i > -1; --i)
    if (n[i].nodeName != '#text' && n[i].childNodes)
    grabTextNodes(n[i].childNodes);
    else
    tn[tn.length] = n[i];
    }, replacements = {
    
        
        '\\ba\\b'     : "_", // \\b added individually for those that we want it for
        '(former director|nuclear watchdog)' : null // set the replacement value to null for those items to get the * treatment
        
        
        }, regex = {};
    
    grabTextNodes(document.body.childNodes);
    
    for (var key in replacements) {
    regex[key] = new RegExp(key, 'gi'); // i added to g for case insensitive regex, removed \\b - now added above
    for (var i = tn.length - 1; i > -1; --i)
    if(replacements[key]) // if a value was specified, use the old method
    tn[i].nodeValue = tn[i].nodeValue.replace(regex[key], replacements[key]);
    // otherwise use the new method of asterisk replacement:
    else tn[i].nodeValue = tn[i].nodeValue.replace(regex[key], function(a){return a.replace(/[^ ]/g, "*");});
    };
    })(); // proper syntax for closing the anonymous function
    Notes:

    • The * replacement regex, [^ ] is changed from . in the link you gave on that, as this will preserve spaces (if any) in the replaced text for bad words only (value null entries).


    • Notice the syntax for bad words use of the () and | tokens. This grouping may also be used with the other syntax:

      Code:
          '\\b(a|and)\\b'     : "_",
      But it needs to go inside the \\b's.

    • I used two word bad words for each. Single word or other multiples may be used. There's no limit to the amount of | symbols:

      Code:
      '(former director|nuclear watchdog|another bad phrase|singlebadword)' : null
      or:

      Code:
      'former director' : null,
      'nuclear watchdog' : null,
      '(another bad phrase|singlebadword)' : null
    - John
    ________________________

    Show Additional Thanks: International Rescue Committee - Donate or: The Ocean Conservancy - Donate or: PayPal - Donate

  10. The Following User Says Thank You to jscheuer1 For This Useful Post:

    bfinoradin (11-29-2010)

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •