Using Methods in Javascript Replace Method

Posted May 15, 2006 at 8:14 AM by Ben Nadel

Tags: Javascript / DHTML

NOTE: For a FULL TUTORIAL on Javascript String Replace methods, check out this entry: Ask Ben: Javascript String Replace Method.

I was just going through some Javascript code when I came across the coolest thing on BigBold.com. I never knew you could do this, but you can use a nameless method as the "replace" argument to the Javascript String replace() method call. See in the example below that I take a string and turn each non-vowel characer into a randomly upper or lowercase character:

  • // Turns the vowel characters into random cases.
  • String.prototype.RandomCase = function(){
  • return(
  • this.replace(
  • new RegExp("([aeiou]{1})", "gi"),  
  • // Here, we are passing in a nameless function as the parameter for
  • // the "replace" argument of the String Replace method. It uses the $1
  • // to refer to the grouping of vowels found in the regular expression.
  • function($1){
  • // Get a random number.
  • if (Math.random() > .5){
  • // Lowercase this one.
  • return( $1.toLowerCase() );
  • } else {
  • // Uppercase this one.
  • return( $1.toUpperCase() );
  • }
  • }
  • )
  • );
  • }
  •  
  • // Create a test string with plenty of vowels.
  • var strTest = "Ben Nadel is a Pretty Nice Guy. I really like Kinky Solutions and his Coding Style.";
  •  
  • // Alert the random-cased string.
  • alert( strTest.RandomCase() );

In this case we are using "$1" to keep the usual formatting of Regular Expressions (RegExp), however, we could have easily named the argument strMatch or something along those lines. The groups found in the RegExp match are passed to the function in the order that they appear (ie. $1, $2, $3, etc.).

The "replace" function argument doesn't need to be confined to the scope of the replace() method call. The "replace" argument is a sub-function just like any other sub function and has access to its parent scope. In the following example, we return an array of the small, common words found in the string. We build this array by declaring prior to the replace() method call and then adding to it for each iteration of the replace() match:

  • String.prototype.GetSmallWords = function(){
  • // Declare the array that will hold the small words matches.
  • var arrWords = new Array();
  •  
  • // Take the string value and get copy the small words into an array.
  • this.replace(
  • new RegExp("(a|and|be|do|for|go|he|hi|i|in|is|no|of|on|the|to)", "gi"),
  •  
  • // This replace function takes the word found and adds the
  • // word to the locally-defined array of short words in the
  • // parent function.
  • function( strWord ){
  • arrWords[ arrWords.length ] = strWord;
  • }
  • );
  •  
  • // Return the array of little words.
  • return( arrWords );
  • }
  •  
  • // Create a test string with small words.
  • var strTest = "Ben Nadel is a Pretty Nice Guy. I really like Kinky Solutions and his Coding Style.";
  •  
  • // Alert the array of small words.
  • alert( strTest.GetSmallWords() );



Reader Comments

Nov 30, 2006 at 11:22 AM // reply »
1 Comments

Some of the code in the first example & wording describing it is confusing & possibly misleading:

> function($1){ .... }
>
> The groups found in the RegExp match are passed to the function in the order that they appear (ie. $1, $2, $3, etc.).

The order of parameters passed to any lambda function used in a replace statement is (fullmatchresult, $1, $2 $3, ..)

.. so in your first example, your variable "$1" does not actually equal the $1 result from the regexp match .. it's the full match result.


Nov 30, 2006 at 12:02 PM // reply »
10,640 Comments

You are exactly correct. This was a misunderstanding on my part. I didn't realize quite what was going on until I started using the Java Pattern Matcher. The Java Pattern matcher has a group() method to which you can pass indexes. The method call with no index returns the full match. Seeing this helped me (in some sort of eureka moment) that I didn't fully understand the way Javascript replace was working.

Thanks for pointing that out for others (as I did not update this blog entry).


Jul 3, 2008 at 1:11 AM // reply »
1 Comments

Thank you sooooo much!
I was doing a google search and you lead me right to a solution. :)

I was wondering if arrays could be use with replace as they can in PHP, but if not you gave me another solution for code optimization!


Mar 15, 2009 at 11:21 AM // reply »
1 Comments

So if your description is not exactly correct, could you update you blog or give some reference material? Because I need more than one matches.


Jul 28, 2010 at 4:21 AM // reply »
1 Comments

do you know how to replace the vowels by asterisk?

example i input a word "beta" then the ouput is "b*t*"


Aug 1, 2010 at 7:48 PM // reply »
10,640 Comments

@Faintsmile,

You wouldn't need to use methods in the replace method for that - it would just be a simple regular expression character class:

"beta".replace( new RegExp( "[aeiou]", "gi" ), "*" )


Post A Comment

Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.

Please review the following issues:

Author Name:


Author Email:

Author Website:

Comment:

Supported HTML tags for formatting: <strong>bold</strong>   <em>italic</em>   <code>code</code>







  • Help Wanted - Find Your Next ColdFusion Job
InVision App - Prototyping Made Beautiful With Prototyping Tools Ben Nadel's Company - Epicenter Consulting Recent Blog Comments
Feb 10, 2012 at 7:21 PM
jQuery AJAX Strips Script Tags And Inserts Them After Parent-Most Elements
Update! Instead of $(eval(options.insertAfter)).after(data['insertData']); I now use: var ajaxNode = document.createElement('span'); var parent = $(eval(options.insertAfter))[0].parentNode; ... read »
Feb 10, 2012 at 6:18 PM
jQuery AJAX Strips Script Tags And Inserts Them After Parent-Most Elements
encountered this same, what I consider, jQuery bug last week. I'm building a site in which I load some content via AJAX. This content contains Linkedin share button placeholders which Linkedin API ne ... read »
Feb 10, 2012 at 11:30 AM
Cross-Origin Resource Sharing (CORS) AJAX Requests Between jQuery And Node.js
After you understand the concepts here, this is an awesome cheatsheet for enabling CORS in just about anything http://enable-cors.org/ ... read »
JM
Feb 10, 2012 at 9:10 AM
My Safari Browser SQLite Database Hello World Example
@Amy, Here is a very good tutorial on how to use JOIN: http://www.sqltutorial.org/sqljoin-innerjoin.aspx ... read »
Feb 10, 2012 at 4:42 AM
Building A Twitter-Inspired RESTful API Architecture In ColdFusion
This is great, very useful Ben. I spotted a small typo in the api.cgm listing: <cfthrow type="Unauthroized" /> Cheers Stefan ... read »
Feb 9, 2012 at 10:35 PM
CFDirectory Filtering Uses Pipe Character For Multiple Filters (Thanks Steve Withington)
I was wondering if there would be a filter you could apply so that you got everything but what you included in the filter. As in show me all docs that are not a .pdf. ... read »
Feb 9, 2012 at 10:29 PM
Learning ColdFusion 9: Application-Specific Data Sources
@Ben, No offence, but if people were really wanting advanced features they would be using a platform like ASP.NET MVC. CFML is so structurally compromised as a tag-based scripting language that ... read »
Feb 9, 2012 at 10:03 PM
Subversion - Cleanup Failed To Process The Following Paths
@Leviaguirre, do you still have problems with this? ... read »