Regular Regular Regex Team

Suppose the following line:

some text here [baz|foo] and here [foo|bar|baz] and even here [option].

I only managed to match this ugly regex ( Regex101.com demo ):

/(?:
  \[
    (?:
      \|?
      ([^\|\[\]]+)
    )?
    (?:
      \|?
      ([^\|\[\]]+)
    )?
    (?:
      \|?
      ([^\|\[\]]+)
    )?
  \]
)/ugx

The thing is, I need matches to group by square brackets. So currently I have the result that I need:

[
  {
    "match": 1,
    "children": [
      {
        "group": 1,
        "start": 16,
        "end": 19,
        "value": "baz"
      },
      {
        "group": 2,
        "start": 20,
        "end": 23,
        "value": "foo"
      }
    ]
  },
  {
    "match": 2,
    "children": [
      {
        "group": 1,
        "start": 35,
        "end": 38,
        "value": "foo"
      },
      {
        "group": 2,
        "start": 39,
        "end": 42,
        "value": "bar"
      },
      {
        "group": 3,
        "start": 43,
        "end": 46,
        "value": "baz"
      }
    ]
  },
  {
    "match": 3,
    "children": [
      {
        "group": 1,
        "start": 63,
        "end": 69,
        "value": "option"
      }
    ]
  }
]

The result is correct, but the regular expression is limited by the number of repeating blocks in the pattern. Is there a workaround so that it matches all the parameters in square brackets?

+4
source share
1 answer

, ​​. , :

  • , | .

([^][|]+), :

$pattern = (function () use ($string) {
    $array = [];
    for ($i = 0; $i <= substr_count($string, "|"); $i++) {
        $array[] = $i == 0 ? '([^][|]+)' : '([^][|]+)?';
    }
    return implode("\|?", $array);
})();

:

some text here [baz] and here [you|him|her|foo|bar|baz|foo|option|test] and even here [another].

:

~\[([^][|]+)\|?([^][|]+)?\|?([^][|]+)?\|?([^][|]+)?\|?([^][|]+)?\|?([^][|]+)?\|?([^][|]+)?\|?([^][|]+)?\|?([^][|]+)?]~

:

preg_match_all("~\[$pattern]~", $string, $matches, PREG_SET_ORDER);

, , , - .

  1. .

. , . :

// Capture strings between brackets
preg_match_all('~\[([^]]+)]~', $string, $matches);

$groups = [];

foreach ($matches[1] as $values) {
    // Explode them on pipe
    $groups[] = explode('|', $values);
}

:

Array
(
    [0] => Array
        (
            [0] => baz
        )

    [1] => Array
        (
            [0] => you
            [1] => him
            [2] => her
            [3] => foo
            [4] => bar
            [5] => baz
            [6] => foo
            [7] => option
            [8] => test
        )

    [2] => Array
        (
            [0] => another
        )

)

-

+3

Source: https://habr.com/ru/post/1652359/


All Articles