Home > Back-end >  How do I repeat the same regex pattern for an unspecified number of key value pairs
How do I repeat the same regex pattern for an unspecified number of key value pairs

Time:02-17

I have tried writing a regular expression to extract an unspecified amount of key value pairs split by equals (excluding quotes)

/^EVENTS?(\s([A-Z] )=("([^"]*)"|([^"\s] ))) $/gm

Here are the lines that it should be processing:

EVENT TYPE=CLICK SELECTOR="HTML>BODY>FORM>DIV>INPUT" BUTTON=0
EVENT TYPE=MOUSEDOWN SELECTOR="HTML>BODY>DIV" BUTTON=2
EVENT TYPE=MOUSEDOWN SELECTOR="HTML>BODY>DIV" BUTTON=1
EVENTS TYPE=MOUSEMOVE SELECTOR="HTML>BODY>DIV" POINTS="(813,214),(809,213)"
EVENT TYPE=MOUSEUP POINT="(1329,221)"

It only seems to capture the last key value pair only, not the ones before it. I've tried wrapping it in another capture group, but that doesn't seem to fix it.

CodePudding user response:

I recommend you to use the regex to capture only one group at the time. Change your regex to only capture what you are interested on

/([A-Z] )=("([^"]*)"|([^"\s] ))/g

then use enter image description here

CodePudding user response:

When using Regex methods be sure to know what they return and what they do after a match is found. A match isn't always what you need so groups are crucial. .matchAll() will return an array containing an array for every hit if you apply the spread operator: ... and put it in an empty array []:

 [...string.matchAll(regex)]
 // [[MATCH, GROUP1, GROUP2,...GROUPN], ...[...]]

So in your case every hit involves 2 capturing groups but not the match because it'll have everything, for example in your results a match will look like this:

  POINTS=\"(813,214),(809,213)

Use an array method to extract the second sub[1] and third sub[2] values from each sub-array. In the example below, .flatMap() was used.

   sub[1] = "POINTS" sub[2] = "(813,214),(809,213)"

const data = `EVENT TYPE=CLICK SELECTOR="HTML>BODY>FORM>DIV>INPUT" BUTTON=0
EVENT TYPE=MOUSEDOWN SELECTOR="HTML>BODY>DIV" BUTTON=2
EVENT TYPE=MOUSEDOWN SELECTOR="HTML>BODY>DIV" BUTTON=1
EVENTS TYPE=MOUSEMOVE SELECTOR="HTML>BODY>DIV" POINTS="(813,214),(809,213)"
EVENT TYPE=MOUSEUP POINT="(1329,221)"`;

const findKV = str => {
  const rgx = new RegExp(/\b([A-Z] )\b="*([A-Z0-9>(,)] )/, 'g');
  return [...str.matchAll(rgx)].flatMap((sub, idx) => {
    return [idx   ': Key: '   sub[1]   ' / Value: '   sub[2]]
  });
};

console.log(findKV(data));

  • Related