14

I have stumbled upon $& when I use regular expressions. If I use $1 I get the same result as with $&. What is special with $&, and where is it documented?

When I search for "regular expression +$&" on duckduckgo or google I can't find any relevant matches.

In the example below it is possible to use $1 or $&. What is special about $&, and why does it exist?

See a fiddle with the example

<div id="quotes">
  <ul>
    <li>Поехали!
      <ul>
        <li><b>Let's go!</b></li>
        <li>Variant translations: <b>Let's ride!</b></li>
        <li><b>Let's drive!</b></li>
        <li><b>Off we go!</b></li>
      </ul>
    </li>
  </ul>
  <ul>
    <li><i>Облетев Землю в корабле-спутнике, я увидел, как прекрасна наша планета. Люди, будем хранить и преумножать эту красоту, а не разрушать её!</i>
      <ul>
        <li><b>Orbiting Earth in the spaceship, I saw how beautiful our planet is. People, let us preserve and increase this beauty, not destroy it!</b></li>
      </ul>
    </li>
  </ul>
</div>

<script>
    var quotes = document.getElementById("quotes"),
        html   = quotes.innerHTML,
        match  = /(let)/gi;

    // $1 gives same result
    quotes.innerHTML = html.replace(match, "<mark>$&</mark>");
</script>
emanciperingsivraren
  • 1,215
  • 2
  • 15
  • 27

3 Answers3

12

The $& and $1 are not the same.

You get the same value because you enclosed the whole pattern in a capturing group.

The $& is a backreference to the whole match, while $1 is a backreference to the submatch captured with capturing group 1.

See MDN String#replace() reference:

$&               Inserts the matched substring.
$n or $nn  Where n or nn are decimal digits, inserts the nth parenthesized submatch string, provided the first argument was a RegExp object.

More details on replacement backreferences can be found at regular-expressions.info.

Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
  • Note that `$&` is a handy construct that allows you not to use any capturing groups inside the pattern when you need to reference the whole matched text from the replacement pattern. In most languages (not Perl!) you can safely use this `&$` and omit the outer unescaped parentheses. – Wiktor Stribiżew Dec 29 '15 at 12:16
7

$& is a "replacement" (placeholder for something to be substituted in) for the full match (all the matched text). $1 is a "replacement" for the first capture group.

So:

var str = "test".replace(/s(t)/, "$&$1");

gives us

testt

because the $& is st and the $1 is t.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • 1
    The `$&` and `$n` are not called placeholders, but backreferences. – Wiktor Stribiżew Dec 29 '15 at 12:13
  • 1
    @stribizhev: Not in `replace` they aren't. They're called ["replacements"](http://www.ecma-international.org/ecma-262/6.0/index.html#sec-string.prototype.replace). Backreferences would be *within* the regex, and JavaScript doesn't have them. – T.J. Crowder Dec 29 '15 at 12:13
  • 1
    @T.J.Crowder: According to [regular-expressions.info](http://www.regular-expressions.info/replacebackref.html), they are replacement backreferences. – Wiktor Stribiżew Dec 29 '15 at 12:18
  • @stribizhev: When it comes to canonical names for things, I'll take the specification over some random website. :-) – T.J. Crowder Dec 29 '15 at 12:31
  • Well, backreferences are really very similar to placeholders. Just placeholders *stand for some hardcoded (static) texts* and backreferences *point to dynamic substrings* that are initialized once a match is found. I have just thought this up :) – Wiktor Stribiżew Dec 29 '15 at 12:36
5

$& returns the entire matched string while $1, $2, ... returns the captured match.

Consider the following:

'abc abc'.replace(/(a)(b)./g, '$1'); // a a
'abc abc'.replace(/(a)(b)./g, '$2'); // b b
'abc abc'.replace(/(a)(b)./g, '$&'); // abc abc
Andreas Louv
  • 46,145
  • 13
  • 104
  • 123