1

I'm trying to match a string like this: test0,id=28084 type=high,18765003 138456387

And I'm using this regex:

const str = `test0,id=28084 type=high,18765003 138456387`;

console.log(str.match(/\s*([a-zA-Z0-9\-_.]+)\s*,\s*([a-zA-Z0-9\-_.]+\s*=\s*[a-zA-Z0-9\-_.]+\s*)*\s*,\s*([0-9.]+)\s+([0-9]+)\s*/))

But I am not getting the id part. Just type=high.

Any help is appreciated.

Edit: I see that I will only get the last capture group. But not stated in the question, I need there to be a dynamic number of fields at that point in the string. I'm wondering if there's some other way to accomplish this.

logi-kal
  • 7,107
  • 6
  • 31
  • 43
aa bb
  • 247
  • 3
  • 9
  • If you repeat a capturing group with a * or + quantifier, you will get only the last match for that group. See also https://stackoverflow.com/questions/17393683 – logi-kal Jul 25 '21 at 16:04
  • @horcrux Oh I see. Any idea how I could get the functionality I want with a regex? – aa bb Jul 25 '21 at 16:05
  • Just repeat the same group manually (e.g. https://regex101.com/r/Olhe18/1). – logi-kal Jul 25 '21 at 16:06
  • @horcrux What if I need it to be N number of fields there? – aa bb Jul 25 '21 at 16:07

1 Answers1

2

You can capture in the same group all the key-value pairs and then split them:

const str = `test0,id=28084 type=high,18765003 138456387`;
matches = str.match(/\s*([a-zA-Z0-9\-_.]+)\s*,\s*((?:[a-zA-Z0-9\-_.]+\s*=\s*[a-zA-Z0-9\-_.]+\s*)*)\s*,\s*([0-9.]+)\s*([0-9]+)\s*/)
matches.splice.apply(matches, [2, 1].concat(matches[2].split(/\s+/)));
console.log(matches)

Notice that I changed in your regex the second group from (...)* to ((?:...)*).

logi-kal
  • 7,107
  • 6
  • 31
  • 43