0

I'm currently reading "Learning JavaScript" by Ethan Brown (2016). I'm going through the examples in the Backreferences section and they keep coming up as 'null'. There are two examples.

Example 1: Match names that follow the pattern XYYX.

const promo = "Opening for XAAX is the dynamic GOOG!  At the box office now!";
const bands = promo.match(/(?:[A-Z])(?:[A-Z])\2\1/g);
console.log('bands: '+ bands);//output was null

If I understand the text correctly, the result should be...

bands: XAAX, GOOG

Example 2: Matching single and/or double quotation marks.

//we use backticks here because we're using single and 
//double quotation marks:
const html = `<img alt='A "simple" example,'>` +
`<img alt="Don't abuse it!">`;
const matches = html.match(/<img alt=(?:['"]).*?\1/g);
console.log('matches: '+ matches);//output was null

Again, if I understand the text correctly, the result should not be 'null'. The text doesn't say exactly what the result should be.

I'm at a loss trying to figure out why when I run this in Node.js it keeps giving me 'null' for these two examples. Anyone have any insight?

Rory O'Kane
  • 29,210
  • 11
  • 96
  • 131
Davinna
  • 1
  • 2
  • A tip: if you want to log a variable’s value after a string separated by a space, pass it as another parameter to `console.log`, like `console.log('bands:', bands)`. This has the same effect in Node.js, but in the browser the variable’s value will be rendered nicely inline instead of coerced to a string. – Rory O'Kane Jul 30 '18 at 20:04
  • I have checked the original source (3rd edition) and can confirm: All samples are wrong and using non-capturing groups. – wp78de Jul 30 '18 at 21:16

2 Answers2

2

The problem is that your group there is

(?:['"])

the ?: indicates that it's a non-capturing group - that means that you can't backreference the group (or get the group in your match result). Use plain parentheses instead to indicate that the group should be captured:

const html = `<img alt='A "simple" example,'>` +
`<img alt="Don't abuse it!">`;
const matches = html.match(/<img alt=(['"]).*?\1/g);
console.log('matches: '+ matches);
CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
0

Looks like an error in the book.

  1. The regex in the code snippets are using non-capturing groups: What is a non-capturing group? What does (?:) do?

These are not usable with back references. Use normal parentheses instead:

const promo = "Opening for XAAX is the dynamic GOOG!  At the box office now!";
const bands = promo.match(/([A-Z])([A-Z])\2\1/g);
console.log('bands: '+ bands);//output was null

The same goes for the other samples...

Update: I have checked the original source (3rd edition) and can confirm: All samples are wrong and using non-capturing groups.

BTW: The author writes:

Grouping enables another technique called backreferences. In my experience, this is one of the least used regex features, but there is one instance where it comes in handy. ...

The only time I think I have ever needed to use backreferences (other than solving puzzles) is matching quotation marks. In HTML, you can use either single or double quotes for attribute values.

And then follows the HTML regex sample shown in the OP. Cthulhu is calling?

wp78de
  • 18,207
  • 7
  • 43
  • 71