Special $ References In JavaScript's String.replace() Method

Posted May 25, 2011 at 9:29 AM by Ben Nadel

Tags: Javascript / DHTML

In honor of the 4th Annual Regular Expression Day, I thought I would do some further exploration of Regular Expressions. And, as it so happens, I just learned something new about Javascript regular expressions while reading Javascript: The Good Parts by Douglas Crockford. In the book, Crockford outlines the special characters that are available in the String.replace() method. I had always known about the use of $N to denote captured groups; I was not aware, however, that $&, $`, and $' were also available in the replace() method.

I don't have Javascript: The Good Parts in front of me at the moment. However, I was able to double-check the syntax on Jan Goyvaerts' website (co-author of The Regular Expression Cookbook). On his website, Jan outlines the above replacement references as follows:

  • $& - Refers to the entire text of the current pattern match.
  • $` - Refers to the text to the left of the current pattern match.
  • $' - Refers to the text to the right of the current pattern match.

To see these references in action, I set up the following demo. In this code, our replacement execution is completely non-functional; it is meant only to elucidate the values contained within each replacement reference:

  • <!DOCTYPE html>
  • <html>
  • <head>
  • <title>Using The $ In JavaScript RegEx Replace</title>
  • <script type="text/javascript">
  •  
  •  
  • // Create a test string in which we will match our pattern.
  • var value = "My number is 212-555-1234.";
  •  
  • // Creat the pattern to match the phone number.
  • var pattern = new RegExp( "(\\d+)", "g" );
  •  
  • // Replace into the value the special "$"-based matches.
  • var result = value.replace(
  • pattern,
  • "|-- [$&] [$`] [$'] --|"
  • );
  •  
  • // Output the replacement result to see $ functionality.
  • console.log( result );
  •  
  •  
  • </script>
  • </head>
  • <body>
  • <!-- Left intentionally blank. -->
  • </body>
  • </html>

As you can see in the above code, we are matching each individual group of digits within the phone number contained within the source text. When we execute the String.replace() method, we're simply replacing the captured number with each of the above $-based values.

When we run the above code, we get the following console output:

My number is |-- [212] [My number is ] [-555-1234.] --|-|-- [555] [My number is 212-] [-1234.] --|-|-- [1234] [My number is 212-555-] [.] --|.

This is a little bit hard to read, so I'm going to break out the replacement portion of each match on its own line:

|-- [212] [My number is ] [-555-1234.] --|
|-- [555] [My number is 212-] [-1234.] --|
|-- [1234] [My number is 212-555-] [.] --|.

As you can see, the $& referred to the entire matched pattern (in our case, that was also the first captured group and could be referred to as $1). The &` referred to the entire text value of the source to the left of the current match. And, the $' referred to the entire text value of the source text to the right of the current match.

I can understand the usefulness of $& in order to refer to the match without having to employ a captured group. But, to be honest, I can't quite see how I would ever use the $` and $' references in a Javascript regular expression replace. In any case, it's always fun to learn more about how something works, even if the value of it is not immediately evident.




Reader Comments

May 25, 2011 at 10:11 AM // reply »
24 Comments

Nice one Ben. I can see the usefulness of having the entire match available.


May 25, 2011 at 4:35 PM // reply »
270 Comments

@Ben: They're available in Perl too.

http://www.regular-expressions.info/perl.html

At the beginning of Chapter 7 - Regular Expressions, Crockford says that the JS implementation is very close to the original Bell Labs formulations, with some reinterpretations and extensions from Perl. But I don't know whether these 3 back references came from Bell Labs or Perl.


May 25, 2011 at 4:48 PM // reply »
11,238 Comments

@Andy,

Word up.

@WebManWalking,

Apparently there are also some other $-based references available, but they are browser extensions and are not universally supported by the browsers.


May 25, 2011 at 4:55 PM // reply »
1 Comments

Regular expressions are literals in ECMAscript. Every regex function is available everywhere.


May 25, 2011 at 5:01 PM // reply »
11,238 Comments

@John,

I use the literal notation every now and then, but sometimes I find it hard to swallow. I find that I get a lot of weird slash patterns. It's probably just what I'm used to - I find this:

"\\bfoo\\b"

... easier to read:

/\bfoo\b/

The latter just throws me off with the flippy-floppy slashes.

Just personal preference, though.


Jun 1, 2011 at 10:51 AM // reply »
1 Comments

In a sort of proof-of-concept use of $` and $', you could parse with two regular expressions to get the text between two tags.

You could run the regular expression for the start tag and get $' for everything to the right (or after). With that result you run the regular expression for the end tag and use $` for everything to the left (or before) and you then get the text in between the two tags.

I'm not saying it's the most practical way, but would allow you to find text after some flag you denote as note-worthy. The more practical use of those two, I'm not really sure.


Jun 1, 2011 at 11:02 AM // reply »
11,238 Comments

@John,

I kind of see what you're saying. I'd have to play around with it a bit to wrap my head around it.


Sep 14, 2012 at 3:38 PM // reply »
1 Comments

Wow that just made my life a whole lot easier. It makes for a great string highlighter:

  • if(typeof String.prototype.highlight !== 'function') {
  • String.prototype.highlight = function(match, spanClass) {
  • var pattern = new RegExp( match, "gi" ),
  • highlight = "<span class='" + spanClass + "'>$&</span>";
  •  
  • return this.replace(pattern, highlight);
  • }
  • }


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
Ben Nadel's Company - Epicenter Consulting Recent Blog Comments
May 21, 2013 at 7:46 PM
Using Plupload For Drag & Drop File Uploads In ColdFusion
No luck. At least I have uncovered the cause, URLScan 3.1. Here is what I see in the IIS log when a file is over 30mb. 2013-05-21 23:29:05 10.105.45.128 GET /plupload/assets/jquery/jquery-1.8. ... read »
May 21, 2013 at 6:12 PM
Using Plupload For Drag & Drop File Uploads In ColdFusion
Ben, I did not see you after Pete Freitag's Lockdown session at cfObjective but he said that IIS sets file size limits at 30MB by default which just happened to be the threshold for file size when ... read »
May 21, 2013 at 11:51 AM
Ask Ben: Parsing Very Large XML Documents In ColdFusion
Looking at my first ever XML document that I have to parse and put into MS SQL 2000 with CF8. I get it to list the desired Field name, many times over, and have a long list of this field name displa ... read »
May 21, 2013 at 9:25 AM
Turning Off and On Identity Column in SQL Server
you are awesome..i am lucky to get this blog between such a garbage one....Thanks, Prashant ... read »
May 20, 2013 at 4:38 PM
Using A Dynamic Column Name With ValueList() In ColdFusion
@Dana, Your confusion is well founded, since this is a very confusing features. In fact, it ONLY works if you use array notation. Meaning, that this: arrayToList( query[ "columnName" ] ) ... read »
May 20, 2013 at 4:34 PM
Using A Dynamic Column Name With ValueList() In ColdFusion
I was thinking chicken and the egg, I wouldn't have expected it to work in the valuelist going in I guess. Maybe I just need a beer, long day :) ... read »
May 20, 2013 at 4:29 PM
Using A Dynamic Column Name With ValueList() In ColdFusion
@Dana, That's if you're trying to reference a specific row. In this case, we're trying to reference the entire query column as one cohesive value. So, you are correct that if you wanted to output a ... read »
May 20, 2013 at 4:24 PM
Using A Dynamic Column Name With ValueList() In ColdFusion
I thought when you used array notation to reference queries you always had to have the row or it would throw a similar error as well? ... read »
InVision App - Prototyping Made Beautiful With Prototyping Tools