4

What I Tried

var test = "asdfdas ABCD EFGH";
var regex = /^\S+( [A-Z]{4})+$/; 
    // Also tried: /^\S+( [A-Z]{4})+$/g
    // And: /^\S+( [A-Z]{4})+?$/g
var matches = test.match(regex);

I made a JSFiddle.

What I Expect

The variable matches should become this array:

[
  "asdfdas ABCD EFGH",
  " ABCD",
  " EFGH"
]

What I Get

The variable matches is actually this array:

[
  "asdfdas ABCD EFGH",
  " EFGH"
]

My Thoughts

My guess is that there's something I'm missing with the capture group and/or $ logic. Any help would be appreciated. (I know I can figure out how to do this in multiple regular expressions, but I want to understand what is happening here.)

Alan Moore
  • 73,866
  • 12
  • 100
  • 156
NoBrainer
  • 5,853
  • 1
  • 27
  • 27
  • 4
    Yes, that’s exactly what it does; you’re not doing anything wrong. When a group is given a quantifier, it only captures its last match, and that’s all it will ever do in JavaScript. The general fix is to use multiple regular expressions, as you said. – Ry- Nov 24 '14 at 18:45
  • That’s not a correct duplicate, @anubhava; there’s no `/g` flag. – Ry- Nov 24 '14 at 18:49
  • 2
    Sorry you can link another Q&A with more answers but idea is same to call `re.exec()` in a `while` loop to get all the matches. Using `g` flag is indeed the correct way here to find multiple matches. – anubhava Nov 24 '14 at 18:50
  • Get rid of `$`. Right now you're only testing for `\w{4}` as it occurs at the end of the string. – rojo Nov 24 '14 at 18:57
  • 1
    The pattern backtracking happens twice. It is the expected behaviour. – hjpotter92 Nov 24 '14 at 19:09
  • AFAIK, only .NET's regex engine lets you extract all the captures for a given group (it actually has a capture stack). But in JS, you have to do what anubhava said. – Lucas Trzesniewski Nov 24 '14 at 23:47
  • @minitech I'm going to edit my question to be more informative. Write up the answer, and you'll get yourself a green check. :) – NoBrainer Nov 25 '14 at 03:27
  • hope this will be of help http://stackoverflow.com/questions/17393683/regex-only-capturing-last-instance-of-capture-group-in-match – Tejesh Nov 25 '14 at 07:13

1 Answers1

3

Yes, that’s exactly what it does; you’re not doing anything wrong. When a group is given a quantifier, it only captures its last match, and that’s all it will ever do in JavaScript. The general fix is to use multiple regular expressions, as you said, e.g.

var test = "asdfdas ABCD EFGH";
var match = test.match(/^\S+((?: [A-Z]{4})+)$/); // capture all repetitions
var matches = match[1].match(/ [A-Z]{4}/g); // match again to get individual ones
Ry-
  • 218,210
  • 55
  • 464
  • 476