preg_match 无条件 return 不匹配的可选捕获组的键
preg_match unconditionally return key for unmatched optional capture group
$pattern = "/^(?<animal>DOG|CAT)?(?<color>BLUE|RED)?$/i";
$str = "DOG";
preg_match($pattern, $str, $matches);
$matches = array_filter($matches, 'is_string', ARRAY_FILTER_USE_KEY);
// $str = "dog" returns [animal] => DOG
//$str = "dogBLUE" returns [animal] => dog and [color] => BLUE
print_r($matches);
我也有例子http://sandbox.onlinephpfunctions.com/code/2428bc68adcf9929557d86dc1ae72552c3681b58
两个命名的捕获组都是可选的,因此 keys
只有在找到匹配项时才会 returned。
我的问题
我如何无条件地 return 为任何可能的命名捕获组设置密钥?如果找不到组,空字符串 '' 会很棒。
输入“DOG”导致 [animal] => 'DOG', [color] => ''
正是我要找的。
我希望 preg_match
上有一个标志来执行此操作,但找不到任何东西。
更新: 我只是想避免做 isset($matches[OPTIONAL_GROUP])
谢谢!
您可以使用 andre at koethur dot de's solution:
$pattern = "/^(?<animal>DOG|CAT)?(?<color>BLUE|RED)?$/i";
$str = "DOG";
if (preg_match($pattern, $str, $matches)) {
$matches = array_merge(array('animal' => '', 'color' => ''), $matches);
$matches = array_filter($matches, 'is_string', ARRAY_FILTER_USE_KEY);
print_r($matches);
}
参见PHP demo。
输出:
Array
(
[animal] => DOG
[color] =>
)
这个想法是您需要“为您感兴趣的所有子模式分配一个名称,然后将 $matches
与包含一些合理默认值的常量数组合并”。
允许重复命名捕获(使用 J 或使用 (?J)
for PHP < 7.3)并在模式开始时初始化您需要的组:
~ (?<animal>) (?<color>)
^ (?<animal>DOG|CAT)? (?<color>RED|BLUE)? $
~xiJ
优点:可以选择结果数组中分组的顺序。
或者不改变你的模式:
$arr = ['animal' => '', 'color' => ''];
$result = array_intersect_key($matches, $arr) + $arr;
注意:array_intersect_key($matches + $arr, $arr)
产生完全相同的结果。
$pattern = "/^(?<animal>DOG|CAT)?(?<color>BLUE|RED)?$/i";
$str = "DOG";
preg_match($pattern, $str, $matches);
$matches = array_filter($matches, 'is_string', ARRAY_FILTER_USE_KEY);
// $str = "dog" returns [animal] => DOG
//$str = "dogBLUE" returns [animal] => dog and [color] => BLUE
print_r($matches);
我也有例子http://sandbox.onlinephpfunctions.com/code/2428bc68adcf9929557d86dc1ae72552c3681b58
两个命名的捕获组都是可选的,因此 keys
只有在找到匹配项时才会 returned。
我的问题
我如何无条件地 return 为任何可能的命名捕获组设置密钥?如果找不到组,空字符串 '' 会很棒。
输入“DOG”导致 [animal] => 'DOG', [color] => ''
正是我要找的。
我希望 preg_match
上有一个标志来执行此操作,但找不到任何东西。
更新: 我只是想避免做 isset($matches[OPTIONAL_GROUP])
谢谢!
您可以使用 andre at koethur dot de's solution:
$pattern = "/^(?<animal>DOG|CAT)?(?<color>BLUE|RED)?$/i";
$str = "DOG";
if (preg_match($pattern, $str, $matches)) {
$matches = array_merge(array('animal' => '', 'color' => ''), $matches);
$matches = array_filter($matches, 'is_string', ARRAY_FILTER_USE_KEY);
print_r($matches);
}
参见PHP demo。 输出:
Array
(
[animal] => DOG
[color] =>
)
这个想法是您需要“为您感兴趣的所有子模式分配一个名称,然后将 $matches
与包含一些合理默认值的常量数组合并”。
允许重复命名捕获(使用 J 或使用 (?J)
for PHP < 7.3)并在模式开始时初始化您需要的组:
~ (?<animal>) (?<color>)
^ (?<animal>DOG|CAT)? (?<color>RED|BLUE)? $
~xiJ
优点:可以选择结果数组中分组的顺序。
或者不改变你的模式:
$arr = ['animal' => '', 'color' => ''];
$result = array_intersect_key($matches, $arr) + $arr;
注意:array_intersect_key($matches + $arr, $arr)
产生完全相同的结果。