Manuel Pardo
Manuel Pardo

Reputation: 731

Regex to extract multidimensional keys using bracket notation

I need to retrieve all keys using pure regex. I need to start with word field and after that need to capture all multiple keys..

field[somevalue][anothervalue]

I'm using this regex: /^field(?=\[(\w+)](?=\[(\w+)])?)/

But I can retrieve only two levels (somevalue and anothervalue)

I need to go deep and retrieve another levels like:

field[somevalue][anothervalue][other][some]...

So I need to retrieve somevalue, anothervalue, other, some and so on, starting with variable name field

I don't want to use loops like this (Regex for bracket notation of multi-dimensional array)

Need to pass directly and use in https://regex101.com

Upvotes: 1

Views: 79

Answers (3)

Cary Swoveland
Cary Swoveland

Reputation: 110735

Here are two more approaches that could be taken if it were known that "field" were present in the string.

#1 Use a negative lookahead

(?<=\[)[^]]*(?=])(?!.*\bfield)

Demo

#2 Match unwanted strings, match and capture wanted strings

.*\bfield\[|\]\[|([^\]]+)

Demo

With this approach strings that are matched but not captured are discarded; the only matches of interest are those that are (matched and) captured (to capture group 1).

Upvotes: 0

The fourth bird
The fourth bird

Reputation: 163577

Using pcre, if "field" should be present, you can make use of a capture group and the \G anchor capturing in the word characters between the square brackets:

(?:\bfield|\G(?!\A))\[(\w+)\]

The pattern matches:

  • (?: Non capture group for the alternatives:
    • \bfield A word boundary, then match "field"
    • | Or
    • \G(?!\A) Assert the current postion at the end of the previous match, not at the start of the string
  • ) Close the non capture group
  • \[(\w+)\] Capture 1+ word chars between square brackets in group 1

See a regex demo.

Or a bit more broader match using a negated character class not matching [ and ] in between the square brackets:

(?:\bfield|\G(?!\A))\[([^][]*)\]

See another regex demo.

Upvotes: 2

Bohemian
Bohemian

Reputation: 425288

Start the match with either a look behind for field or the end of the previous match (\G):

(?<=field|\G)\[(.*?)]

See live demo.

Upvotes: 1

Related Questions