El Ronnoco
El Ronnoco

Reputation: 11922

Why does this RegExp match two strings?

var str = "abcd1234";
var first = str.match(/^abcd(\d+)$/)[0]; //matches abcd1234
var number = str.match(/^abcd(\d+)$/)[1]; //matches 1234 only

Why does this regex first match the whole of str and then match the numeric part? Looking at it I'd say it would always have to match abcd and then 1 or more digits? Isn't the 'abcd' a mandatory part of the match?

Incidentally I found this regex as part of this question.

Thanks.

Upvotes: 1

Views: 281

Answers (4)

David
David

Reputation: 63

Any part of your regex in brackets '( )' becomes a grouping. This portion of the match is then also returned when you match your regex. This can be useful if you want to match a pattern and then use different parts of it for processing (eg a list of key value pairs in the format "key:value" you could make a group for key and for the value).

You can make a grouping non capturing by placing '?:' after the first bracket. The following will match your regex and not capture the grouping/brackets part:

var first = str.match(/^abcd(?:\d+)$/)[0]; //returns abcd1234 ONLY

Also gskinner has a nice regex tester that will show you the groupings for your regex (hover over blue highlighted text).

Upvotes: 0

Antoine Pelisse
Antoine Pelisse

Reputation: 13109

It's because 0 refers to the whole match while 1 refers to the first parenthezised group (which is actually 1234)

You could have this for example:

var str = "abcd1234";
var first = str.match(/^(abcd)(\d+)$/)[0]; //returns abcd1234
var chars = str.match(/^(abcd)(\d+)$/)[1]; //returns abcd only
var number = str.match(/^(abcd)(\d+)$/)[2]; //returns 1234 only

Upvotes: 6

wombleton
wombleton

Reputation: 8376

https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/RegExp

The capturing parentheses store the match from that part of the regex and hold it separate from the first result, which is the whole match.

Upvotes: 0

Michielvv
Michielvv

Reputation: 346

It is normal in regex match results for [0] to be the whole match. and then [1]...etc. to contain the partial matches. If you want both first and second part from the match, you will need to write something like:

  var m = str.match(/^(abcd)(\d+)$/);
  var wholematch = m[0];
  var first = m[1];
  var num = m[2];

Upvotes: 2

Related Questions