Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Regexp to capture comma separated values

I have a string that can be a comma separated list of \w, such as:

  • abc123
  • abc123,def456,ghi789

I am trying to find a JavaScript regexp that will return ['abc123'] (first case) or ['abc123', 'def456', 'ghi789'] (without the comma).

I tried:

  • ^(\w+,?)+$ -- Nope, as only the last repeating pattern will be matched, 789
  • ^(?:(\w+),?)+$ -- Same story. I am using non-capturing bracket. However, the capturing just doesn't seem to happen for the repeated word

Is what I am trying to do even possible with regexp? I tried pretty much every combination of grouping, using capturing and non-capturing brackets, and still not managed to get this happening...

like image 200
Merc Avatar asked Dec 26 '22 04:12

Merc


2 Answers

If you want to discard the whole input when there is something wrong, the simplest way is to validate, then split:

if (/^\w+(,\w+)*$/.test(input)) {
    var values = input.split(',');

    // Process the values here
}

If you want to allow empty value, change \w+ to \w*.

Trying to match and validate at the same time with single regex requires emulation of \G feature, which assert the position of the last match. Why is \G required? Since it prevents the engine from retrying the match at the next position and bypass your validation. Remember than ECMA Script regex doesn't have look-behind, so you can't differentiate between the position of an invalid character and the character(s) after it:

something,=bad,orisit,cor&rupt
          ^^             ^^

When you can't differentiate between the 2 positions, you can't rely on the engine to do a match-all operation alone. While it is possible to use a while loop with RegExp.exec and assert the position of last match yourself, why would you do so when there is a cleaner option?


If you want to savage whatever available, torazaburo's answer is a viable option.

like image 132
nhahtdh Avatar answered Dec 27 '22 19:12

nhahtdh


Live demo

Try this regex :

'/([^,]+)/'

Alternatively, strings in javascript have a split method that can split a string based on a delimeter:

s.split(',')
like image 32
CMPS Avatar answered Dec 27 '22 18:12

CMPS