正则表达式,从“:key{value}”等数组中过滤预期数据


Regular expression, filtering expected data from an array like ":key{value}"

示例:

$match_check = "(?'txt'(?<=:txt{)([^}]+)(?=}))|(?'reg'(?<=:reg{)([^}]+)(?=}))";
$route_from_value = ':txt{resultxt}:txt{test}:reg{/^[a-zA-Z]*$/}:reg{regexresult}';
preg_match_all('/'.$match_check.'/', $route_from_value, $get_matchers_check);
var_dump($get_matchers_check);

给定问题的结果是:

array(7) {
  [0] =>
  array(4) {
    [0] =>
    string(8) "resultxt"
    [1] =>
    string(4) "test"
    [2] =>
    string(13) "/^[a-zA-Z]*$/"
    [3] =>
    string(11) "regexresult"
  }
  'txt' =>
  array(4) {
    [0] =>
    string(8) "resultxt"
    [1] =>
    string(4) "test"
    [2] =>
    string(0) ""
    [3] =>
    string(0) ""
  }
  [1] =>
  array(4) {
    [0] =>
    string(8) "resultxt"
    [1] =>
    string(4) "test"
    [2] =>
    string(0) ""
    [3] =>
    string(0) ""
  }
  [2] =>
  array(4) {
    [0] =>
    string(8) "resultxt"
    [1] =>
    string(4) "test"
    [2] =>
    string(0) ""
    [3] =>
    string(0) ""
  }
  'reg' =>
  array(4) {
    [0] =>
    string(0) ""
    [1] =>
    string(0) ""
    [2] =>
    string(13) "/^[a-zA-Z]*$/"
    [3] =>
    string(11) "regexresult"
  }
  [3] =>
  array(4) {
    [0] =>
    string(0) ""
    [1] =>
    string(0) ""
    [2] =>
    string(13) "/^[a-zA-Z]*$/"
    [3] =>
    string(11) "regexresult"
  }
  [4] =>
  array(4) {
    [0] =>
    string(0) ""
    [1] =>
    string(0) ""
    [2] =>
    string(13) "/^[a-zA-Z]*$/"
    [3] =>
    string(11) "regexresult"
  }
}

但是,预期的结果应该是(如何仅使用正则表达式?)或简单地:

 'txt' =>
  array(4) {
    [0] =>
    string(8) "resultxt"
  },
 'txt' =>
  array(4) {
    [0] =>
    string(8) "resultxt"
  }
 'reg' =>
  array(4) {
    [0] =>
    string(8) "/^[a-zA-Z]*$/"
  }
 'reg' =>
  array(4) {
    [0] =>
    string(8) "regexresult"
  }

preg_match_allpreg_split 函数的输出遵循与您想要的不匹配的格式。

您可以做的是对preg_match_all的输出进行一些后处理以获得结果(类似于['key', 'value']对数组)。请注意,您应该设置标志PREG_OFFSET_CAPTURE以获取匹配的索引进行比较。与任何内容都不匹配的捕获组将提供索引-1,或者不会返回包含 2 个元素的数组。

顺便说一下,您可以从正则表达式中删除一些不必要的捕获组。

"(?'txt'(?<=:txt{)[^}]+(?=}))|(?'reg'(?<=:reg{)[^}]+(?=}))"

示例运行:

$matches = null;
$returnValue = preg_match_all('/(?''txt''(?<=:txt{)[^}]+(?=}))|(?''reg''(?<=:reg{)[^}]+(?=}))/', ':txt{resultxt}:txt{test}:reg{/^[a-zA-Z]*$/}:reg{regexresult}', $matches, PREG_OFFSET_CAPTURE);

输出:

array (
  0 => 
  array (
    0 => 
    array (
      0 => 'resultxt',
      1 => 5,
    ),
    1 => 
    array (
      0 => 'test',
      1 => 19,
    ),
    2 => 
    array (
      0 => '/^[a-zA-Z]*$/',
      1 => 29,
    ),
    3 => 
    array (
      0 => 'regexresult',
      1 => 48,
    ),
  ),
  'txt' => 
  array (
    0 => 
    array (
      0 => 'resultxt',
      1 => 5,
    ),
    1 => 
    array (
      0 => 'test',
      1 => 19,
    ),
    2 => // No match found, index -1
    array (
      0 => '',
      1 => -1,
    ),
    3 => // No match found, index -1
    array (
      0 => '',
      1 => -1,
    ),
  ),
  1 => 
  array (
    0 => 
    array (
      0 => 'resultxt',
      1 => 5,
    ),
    1 => 
    array (
      0 => 'test',
      1 => 19,
    ),
    2 => 
    array (
      0 => '',
      1 => -1,
    ),
    3 => 
    array (
      0 => '',
      1 => -1,
    ),
  ),
  'reg' => 
  array (
    0 => '', // No match found, not array of 2 elements [<matched text>, <index>]
    1 => '', // No match found, not array of 2 elements [<matched text>, <index>]
    2 => 
    array (
      0 => '/^[a-zA-Z]*$/',
      1 => 29,
    ),
    3 => 
    array (
      0 => 'regexresult',
      1 => 48,
    ),
  ),
  2 => 
  array (
    0 => '',
    1 => '',
    2 => 
    array (
      0 => '/^[a-zA-Z]*$/',
      1 => 29,
    ),
    3 => 
    array (
      0 => 'regexresult',
      1 => 48,
    ),
  ),
)