如何仅返回具有preg_match或preg_match_all的命名组?

2022-08-30 18:26:44

例:

$string = "This is some text written on 2010-07-18.";
preg_match('|(?<date>\d\d\d\d-\d\d-\d\d)|i', $string, $arr_result);
print_r($arr_result);

返回:

Array
(
    [0] => 2010-07-18
    [date] => 2010-07-18
    [1] => 2010-07-18
)

但我希望它是:

Array
(
    [date] => 2010-07-18
)

在PHP的PDO对象中,有一个选项通过删除这些重复的编号值来过滤数据库中的结果:PDO::FETCH_ASSOC。但是我还没有在PHP中看到PCRE函数的类似修饰符。


答案 1

如何仅返回具有preg_match或preg_match_all的命名组?

这目前(PHP7)是不可能的。您将始终获得一个混合类型数组,其中包含数字和命名键。

让我们引用PHP手册(http://php.net/manual/en/regexp.reference.subpatterns.php):

然后,此子模式将按其正常数字位置和名称在匹配数组中编制索引。


要解决此问题,以下代码片段可能会有所帮助:

1. 使用数组键的is_string检查来过滤数组(对于 PHP5.6+)

$array_filtered = array_filter($array, "is_string", ARRAY_FILTER_USE_KEY);

2. foreach over elements 和 unset if array key is_int() (所有 PHP 版本)

/**
 * @param array $array
 * @return array
 */
function dropNumericKeys(array $array)
{
    foreach ($array as $key => $value) {
        if (is_int($key)) {
            unset($array[$key]);
        }
    }
    return $array;
}

它是一个名为 的简单 PHP 函数。它用于在运行后使用命名组进行匹配的匹配数组的后处理。这些函数接受 .它迭代数组并删除/取消设置所有具有整数类型的键,使字符串类型的键保持不变。最后,该函数返回仅包含“now”命名键的数组。dropNumericKeys()preg_match*()$array

注意:该函数用于PHP向下兼容。它适用于所有版本。该解决方案依赖于常量,该常量仅在 PHP5.6+ 上可用。查看 http://php.net/manual/de/array.constants.php#constant.array-filter-use-keyarray_filterARRAY_FILTER_USE_KEY


答案 2

preg_match没有任何标志或选项,它只返回命名匹配项(尚未)。所以你想要的不是直接可能的。但是,您可以从匹配数组中删除所有具有不拟合键的项目,然后获得所需的内容:

$matches = array_intersect_key($matches, array_flip(array('name', 'likes')));

推荐