1

Given myString 6 cyl, 3.2L (3197cc) engine, the following needs to be extracted: 6 cyl and 3197cc.
This code is failing and not sure how to fix it.

const rgx = /(\d cyl).*(\d{2,4}?cc)/g;  //defined outside a loop

//inside the loop we have myString changes every run.
    let match = rgx.exec(myString);
    console.log(match[1]);   // => 6 cyl
    console.log(match[2]);   // => 97cc  <--------- suppose to be 3197cc

Then the next loop around, the whole thing fail to match saying

"Cannot read property '1' of null".

What am I doing wrong?

Tushar
  • 85,780
  • 21
  • 159
  • 179
Fred J.
  • 5,759
  • 10
  • 57
  • 106
  • Lazy: `.*?` & escape the braces ==> [`/(\d cyl).*?\((\d{2,4}?cc)\)/g`](https://regex101.com/r/UhEOnk/1) – Tushar Oct 14 '16 at 03:48
  • Can you add complete code. The loop and the complete string is missing in the question. – Tushar Oct 14 '16 at 04:31

1 Answers1

0

You aren't matching on the surrounding parentheses this is causing the regex to match on smallest match possible (greedy vs non-greedy)

Change your regex to:

/(\d cyl).*\((\d{2,4}cc)\)/g

I removed the ? from the \d{2,4} because based on what you've wrote it sounds like the cc size would be required (and if you really want it optional you'd probably want cc optional as well)

Then on the \((\d{2,4}cc)\) I added the outside parentheses with a backslash preceding them. This is a literal match to a parenthesis which is what is now allowing the regex to work properly.

const rgx = /(\d cyl).*\((\d{2,4}cc)\)/g;  //defined outside a loop

//inside the loop we have myString changes every run.
    let match = rgx.exec('6 cyl, 3.2L (3197cc) engine');
    console.log(match[1]);   // => 6 cyl
    console.log(match[2]);   // => 97cc  <--------- suppose to be 3197cc
Nathan
  • 1,437
  • 12
  • 15