mindparse
mindparse

Reputation: 7225

Regex to capture multiple array index literals inside a string

Probably dead simple for someone out there, but I want to build a regex that will search across this string:

foo[0][2]

and return

foo
0
2

in the array of matches

So far I have come up with is

\([a-z]*)(\[(\d)\])/g

which only gives back

0: "foo[0]"
1: "foo"
2: "[0]"
3: "0"

It's not repeating onto the next literal array in my string, so not hitting the [2] part.

I'm no regex ninja, and would appreciate some assistance with arriving at the correct expression I need.

Thanks

Upvotes: 1

Views: 316

Answers (2)

The fourth bird
The fourth bird

Reputation: 163362

If you use the pattern ([a-z]*)(\[(\d)\]) you could use a while loop to get the first and the third capturing group but note that using [a-z]* matches 0+ times and could also match the parts in [0][2] for example.

const regex = /([a-z]*)(\[(\d)\])/g;
const str = `foo[0][2]`;
let m;
let result = [];
while ((m = regex.exec(str)) !== null) {
  // This is necessary to avoid infinite loops with zero-width matches

  if (m.index === regex.lastIndex) {
    regex.lastIndex++;
  }
  if (m[1] !== "") result.push(m[1]);
  if (m[3] !== "") result.push(m[3]);
}
console.log(result);

If you want to match that exact format, you could use 2 capturing groups to first match foo in group 1 and [0][2] in group 2

\b([a-z]+)((?:\[\d])+)

Explanation

  • \b Word boundary
  • ( Capture group 1
    • [a-z]+ Match 1+ times a char a-z
  • ) Close group
  • ( Capture group 2
    • (?:\[\d])+ Repeat 1+ times matching a single digit between [] (use \d+ to match 1 or more)
  • ) Close group

Regex demo

If that pattern matches you could get all the digits from group 2 as the overall pattern already matches.

const pattern = /\b([a-z]+)((?:\[\d])+)/;
let parts = "foo[0][2]".match(pattern);
console.log([parts[1], ...parts[2].match(/\d/g)]);

Upvotes: 2

Tân
Tân

Reputation: 1

I think you're looking for this pattern: ([a-z]+)|(\[\d\])

console.log('foo[0][2]'.match(/([a-z]+)|(\[\d\])/g));


If you don't want the [] parts, you can try this:

console.log('foo[0][2]'.match(/([a-z]+)|(\d)/g));

Upvotes: 3

Related Questions