Javascript String Replace _ Kinky Solutions by Ben Nadel

Document Sample
Javascript String Replace _ Kinky Solutions by Ben Nadel Powered By Docstoc
					Javascript String Replace @ Kinky Solutions by Ben Nadel                   http://www.bennadel.com/resources/uploads/javascript_string...




           Javascript String Replace
           Javascript's built-in String replace method String::replace() is a pretty darn powerful
           method. It can be used to replace single instances of a substring, global instances, and it can
           even be leveraged to do tasks that have nothing to do with replacing substrings at all.

           Run the Code From Below

           First, we have to create a little text blurb on which to perform our Javascript string replace
           testing.

             var strText =
                 "I saw this girl walking down the street the\n" +
                 "other day as I was leaving work. She had calves\n" +
                 "that were crazy large; so big and round. The kind\n" +
                 "of calves that you'd want to get down on your hands\n" +
                 "and knees just to touch.";


           When doing a simple string replace, only the first instance of the matching string will be
           replaced.

             alert( strText.replace( "th", "[X]" ) );


           If you want to replace more than the first instance, you can start looping over the string
           making replacements until the target string can no longer be found in the string value.

             var strReplaceAll = strText;
             var intIndexOfMatch = strReplaceAll.indexOf( "th" );


             // Loop over the string value replacing out each matching
             // substring.
             while (intIndexOfMatch != -1){
                 // Relace out the current instance.
                 strReplaceAll = strReplaceAll.replace( "th", "[X]" )


                 // Get the index of any next matching substring.
                 intIndexOfMatch = strReplaceAll.indexOf( "th" );
             }


             alert( strReplaceAll );


           Notice that the replace method is CASE SENSITIVE. It went through and replaced out all of
           the "th" instances, but did not replace anything with an upper case T (ex. The). Looping over
           the indexes is a bit of pain in the butt. If you are intending to do this type of operation a lot,
           you might want to consider building a replaceAll() method into the Javascript String object as
           a prototype method so that it would be available to all strings.




1 of 7                                                                                                                   2/7/09 1:40 PM
Javascript String Replace @ Kinky Solutions by Ben Nadel                 http://www.bennadel.com/resources/uploads/javascript_string...



             // Replaces all instances of the given substring.
             String.prototype.replaceAll = function(
                 strTarget, // The substring you want to replace
                 strSubString // The string you want to replace in.
                 ){
                 var strText = this;
                 var intIndexOfMatch = strText.indexOf( strTarget );


                 // Keep looping while an instance of the target string
                 // still exists in the string.
                 while (intIndexOfMatch != -1){
                       // Relace out the current instance.
                       strText = strText.replace( strTarget, strSubString )


                       // Get the index of any next matching substring.
                       intIndexOfMatch = strText.indexOf( strTarget );
                 }


                 // Return the updated string with ALL the target strings
                 // replaced out with the new substring.
                 return( strText );
             }


           Now, replaceAll() is a built in method for all string values. Try performing the same replace
           we did above, but use this built in method instead.

             strReplaceAll2 = strText.replaceAll( "th", "[X]" )


             alert( strReplaceAll2 );


           You will see that it does the same replace with much less code! Not only that, every string
           value in you application can leverage the replaceAll() method once the prototype has been
           defined.

           As you saw above though, the replace is still case sensitive. If you wanted to build a case
           INSENSITIVE replace, you could do so using a modification of the logic above. But, this
           would get very hairy very fast. Instead, you can use a regular expression (often referred to
           as a RegEx or a RegExp). Regular expressions are much more powerful than standard string
           matching as they can use very complicated logic.

             // Let's take a look at the above example using regular expressions.
             strReplaceSimple = strText.replace( new RegExp( "th", "" ), "[X]" );


             alert( strReplaceSimple );


           As you can see, we have the same replace happening. So let's take a look at what's going
           on. Instead of passing simple target string to the replace() method, we are passing in a




2 of 7                                                                                                                 2/7/09 1:40 PM
Javascript String Replace @ Kinky Solutions by Ben Nadel                  http://www.bennadel.com/resources/uploads/javascript_string...


           regular expression (new RegExp()) object instance. The RegExp() takes two arguments, the
           expression and the search flags (left blank in our example). There are two universally valid
           flags: [g] which means globally replace and [i] which
           means case INsensitive. By default, the regular expression is NOT global and case sensitive.

             // So let's try to do a global replace using regular expressions.
             strReplaceAll = strText.replace( new RegExp( "th", "g" ), "[X]" );


             alert( strReplaceAll );


           We just did a global replace in ONE line of code. Compare this to the non-regular expression
           solution which takes 13 lines of code (I am including line breaks and white space in the
           count). Now for the magic... let's do that same thing with out case sensitivity.

             strReplaceAll = strText.replace( new RegExp( "th", "gi" ), "[X]" );


             alert( strReplaceAll );


           We just replaced out that additional "Th" simply by adding the flag [i] into the regular
           expression. That's how powerful regular expressions are. But there's more. Regular
           expressions are more than just flags. Much more!

           Image that for some reason, you knew about regular expressions, but you didn't know about
           the case insensitive flag [i]. You could have performed the same replace using this:

             strReplaceAll = strText.replace( new RegExp( "(T|t)(H|h)", "g" ), "[X]" );


             alert( strReplaceAll );


           This groups the two letters together, and for each letter it tells the replacing algorithm to
           match t OR T followed by h OR H. There is sooo much more that regular expressions can do.
           Unfortunately, that is outside the scope of this entry. You should really look into regular
           expression both in Javascript and in ColdFusion / Java. They are amazing.

           But what happens if you don't want to do a simple replace? The replace method allows some
           very interesting flexibility. Up until now, we have been passing a simple string in a the
           "replace-in" argument ([X]). But, you don't have to. You can pass in a function pointer
           instead.

           For this example, let's replace out the target string with a random letter in the brackets, not
           necessarily the X. First we have to create a function that will return the resultant random
           string.




3 of 7                                                                                                                  2/7/09 1:40 PM
Javascript String Replace @ Kinky Solutions by Ben Nadel                 http://www.bennadel.com/resources/uploads/javascript_string...



             function RandomString(){
                   // Create an array of letters.
                   var arrLetters = ["A","B","C","D","E","V","W","X","Y","Z"];


                   // Use the random() method and the modulus (%) operator to
                   // pick a random letter from the above array.
                   var intLetter = (Math.floor( Math.random() * 10 ) % 9);


                   // Return the random letter string we get from the
                   // array of letters above.
                   return( "[" + arrLetters[ intLetter ] + "]" );
             }


           Try calling the function on its own a few times, just to see how it behaves.

             alert(
                   RandomString() + "\n" + RandomString() + "\n" +
                   RandomString() + "\n" + RandomString() + "\n" +
                   RandomString() + "\n" + RandomString() + "\n" +
                   RandomString() + "\n" + RandomString() + "\n"
                   );


           As you can see, it randomly (as random as possible) picks a letter to return. Now, let's call
           the replace with the RandomString() method sent as the second argument. We will do this a
           few times so you can see the randomness in effect.

             alert( strText.replace( "th", RandomString ) );
             alert( strText.replace( "th", RandomString ) );
             alert( strText.replace( "th", RandomString ) );


           Notice that we are passing in a POINTER to the function but not actually calling it.
           RandomString vs. RandomString(). There's one thing I did not mention yet. Not only can you
           pass in a function as an argument, but when the replace method is taking place, it passes in
           the target match as an argument to this function. We could have re-written the function as
           such:




4 of 7                                                                                                                 2/7/09 1:40 PM
Javascript String Replace @ Kinky Solutions by Ben Nadel                  http://www.bennadel.com/resources/uploads/javascript_string...



             function RandomString2(
                 strTargetInstance // This is the target string match instance.
                 ){
                 var arrLetters = ["A","B","C","D","E","V","W","X","Y","Z"];
                 var intLetter = (Math.floor( Math.random() * 10 ) % 9);


                 // Return the random letter string we get from the
                 // array of letters above. This time, though, we are
                 // going to include the target string to demonstrate
                 // that it has been passed in.
                 return( "[" + strTargetInstance + " : " + arrLetters[ intLetter ] + "]" );
             }


           Now, we will run it again, just once, so you can see it in action.

             alert( strText.replace( "th", RandomString2 ) );


           Notice now that the replace string is the form of [th : X]. That is pretty cool, but it gets even
           cooler. This same methodology applies to doing replacements using regular expressions
           (didn't you have a hunch we'd see them again).

           Just to kick of this demo, I will run the global regular expression replace to show that it
           works the same way.

             alert( strText.replace( new RegExp( "th", "gi" ), RandomString ) );


           Notice that we have now replaced all [g] the case insensitive [i] substring matches with the
           random letter.

           This is very cool, but regular expressions take this even one step further. You can group
           parts of a regular expression and each group will get passed as an argument to the function
           method. In this example, let's group each letter and have them passed as an argument.

             function GroupReplace(
                 strMatchingString, // The entire string matched.
                 strFirstLetter,           // First group from RegExp.
                 strSecondLetter           // Second group from RegExp.
                 ){
                 // Instead of doing any random letter stuff like the
                 // previous examples, we will just place brackets
                 // around each of the groups to demonstrate the
                 // regular expression grouping.
                 return( "[" + strFirstLetter + "][" + strSecondLetter + "]" );
             }


           The one caveat here, that is different from the standard string replace method is that when
           using regular expressions, the first argument passed into the function, like the string
           replace, is the entire matching string.




5 of 7                                                                                                                  2/7/09 1:40 PM
Javascript String Replace @ Kinky Solutions by Ben Nadel                 http://www.bennadel.com/resources/uploads/javascript_string...


           Now, let's run it with groups in the regular expression. Groups are denoted by () around
           parts of the expression. Let's run a global, case insensitive match for a maximum amount of
           fun :)

             alert(
                    strText.replace( new RegExp( "(t)(h)", "gi" ), GroupReplace )
                    )


           Notice that all the instances of "th" were replaced with the case-appropriate "[t][h]"

           So now that we have seen the technicals of the Javascript string replace method, let's
           explore some ways that we can leverage the replace method to do non-replace actions. For
           example, we can use the Javascript string replace method to COUNT the number of times a
           string appears in the given string.

             // This counts the number of times a string matching the
             // given regular expression can be found in the given text.
             function CountValue( strText, reTargetString ){
                    var intCount = 0;


                    // Use replace to globally iterate over the matching
                    // strings.
                    strText.replace(
                         reTargetString,


                         // This function will get called for each match
                         // of the regular expression.
                         function(){
                             intCount++;
                         }
                    );


                    // Return the updated count variable.
                    return( intCount );
             }


           Alert the count of the reg expression.

             alert(
                    "Value Count: " +
                    CountValue( strText, new RegExp( "th", "gi" ) )
                    );


           You might be confused by the nested functions in the example above. Since the function
           being passed to the replace method is a nested function, Javascript will search the local
           variable scope for "intCount." When it cannot find it, it will move up the scope chain to the
           CountValue() function which does contain a variable intCount. This is the variable that will be
           updated for each iteration of the loop.




6 of 7                                                                                                                 2/7/09 1:40 PM
Javascript String Replace @ Kinky Solutions by Ben Nadel                  http://www.bennadel.com/resources/uploads/javascript_string...


           One last example that seems to stump a lot of people is the replacing of strings that span
           multiple lines. In our sample text, the line break "\n" is what creates several lines that we
           can try to match across. The trick is just to treat the "\n" as just another character.

           For this example, we will replace the character "s" that ends a word, followed by any white
           space, until the end of the next word.

             alert(
                 strText.replace( new RegExp( "s\\b[^ ]+", "gi" ), "[X]" )
                 );


           As you can see, the matches were made across the line break with no problem at all. By
           treating the "\n" as just another character that might come up and be matched on, there is
           no problems to worry about. In our example, the clause "[^ ]" will match on any character
           that is NOT a space character. This includes alpha-numeric characters, punctuation, and even
           the new line character.

           One caveat to remember is that while in ColdFusion, new lines that come out of a textarea
           are represented by the character 13 followed by 10, once inside a Javascript string, the new
           line is JUST "\n".

           Well, that's the short and skinny of Javascript String replacement tips and tricks. I am sure
           you are beginning to see just how crazy awesome they can be. And, if you don't know your
           regular expressions, I hope that this little tutorial has piqued your interests. They will change
           your life.



           Copyright Ben Nadel @ Kinky Solutions
           Updated on July 19, 2006




7 of 7                                                                                                                  2/7/09 1:40 PM

				
DOCUMENT INFO
Categories:
Tags:
Stats:
views:10
posted:6/22/2012
language:English
pages:7