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

Php 如何仅返回具有preg_match或preg_match_all的命名组?,php,regex,preg-match,Php,Regex,Preg Match,例如: $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 ( [date] => 2010-07-18 ) 在PHP的PDO对象中,有一个选项通过删除这些重复的编号值来过滤数据库中的结果:。但是我还没有看

例如:

$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
(
    [date] => 2010-07-18
)

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

我认为你不能让
preg.*
这样做,但是你可以用一个简单的循环来做。但我不明白为什么这些元素会带来问题。

试试这个:

$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);
echo $arr_result['date'];
$string=“这是一些写在2010-07-18上的文本。”;
preg_match(“|)(?\d\d\d-\d\d-\d\d)| i“,$string,$arr_result);
echo$arr_结果['date'];
没有任何标志或选项,它只返回命名的匹配项(尚未)。所以你想要的不是直接可能的。但是,您可以从matches数组中删除所有具有非拟合关键点的项目,然后获得所需的:

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

还可以在返回之前取消设置所有数值索引:

foreach (range(0, floor(count($arr_result) / 2)) as $index) {
    unset($arr_result[$index]);
}
与上面hakre发布的内容类似,我使用此代码段仅获取命名参数:

$subject = "This is some text written on 2010-07-18.";
$pattern = '|(?<date>\d\d\d\d-\d\d-\d\d)|i';
preg_match_all($pattern, $subject, $matches, PREG_SET_ORDER);
echo '<pre>Before Diff: ', print_r($matches, 1), '</pre>';
$matches = array_diff_key($matches[0], range(0, count($matches[0])));
echo '<pre>After Diff: ', print_r($matches, 1), '</pre>';
如何仅返回具有preg_match或preg_match_all的命名组

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

让我们引用PHP手册():

然后,该子模式将通过其 正常数字位置和名称


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

1。通过使用数组键上的is_字符串检查来筛选数组(适用于PHP5.6+)

2。foreach覆盖元素,如果数组键为_int()(所有PHP版本)则取消设置

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


注意:该函数用于PHP向下兼容。它适用于所有版本。
array\u filter
解决方案依赖于常量
array\u filter\u USE\u KEY
,该项仅在PHP5.6+上可用。请看

我在你的帖子中读到,这些可能是未来内存过载等。。。 在这种情况下,为什么不能使用unset()来解决:

<?php
$subject = "This is some text written on 2010-07-18.";

pattern('(?<date>\d\d\d\d-\d\d-\d\d)', 'i')->match($subject)->first(function ($match) {

    $date = $match->get('date'); 
    // 2010-07-18

    $groups = $match->namedGroups(); 
    // [
    //   'date' => '2010-07-18'
    // ]   
});
$string=“这是一些写在2010-07-18上的文本。”;
preg_match('|(?\d{4}-\d{2}-\d{2})|i',$string,$arr_result);
$date=数组(“日期”=>$arr_结果['date']);
未设置($arr_result,$string)//删除数组和字符串preg_match origen
打印(日期);
//或创建一个新的:
//$arr_result=$date;
//打印($arr_结果);

我使用了一些介绍的代码,这是PHP5.6+上的最终代码:

$re='/\d+\r\n(?[\d\0:]+),\d+\s-->\s(?[\d\0:]+),.\r\nHOME.*\r\nGPS\(?[\d\.]+),(?[\d\.]+),(?[\d\.]+)\sBAROMETER\:(?[\d\.]+)/;
$str=文件获取内容($srtFile);
预匹配全部($re,$str,$matches,预设置顺序,0);
回声';
$filtered=数组映射(函数($d){
返回$array\U FILTED=array\U filter($d,“是字符串”,array\U filter\U USE\U键);
}(港币),;
var_转储(已过滤);
如果您对它的功能感兴趣,它会从DJI无人机录制视频时生成的str文件中读取位置数据。

您可以使用并使用
group()
namedGroups()
,它只返回命名的捕获组


在小型阵列中,这不会造成问题,但在具有大量模式的大型阵列中,可能存在内存需求高的问题。第二,这样看起来更干净,而且(使用这个不存在的修饰符)会少一行代码,因此出错的可能性更小。恰恰相反:因为PCRE无法做到这一点,所以您必须添加更多的代码,这可能会有更多的问题。我指的是数组中的附加元素。相反,如果我要求的这个修饰符存在,那么就不需要额外的一行了,如果它是一个全局修饰符,可以设置输出数组的所有pcre函数设置模式的首选项,那就更好了。我重复一遍:它是在PDO对象中完成的,在pcre中不能完成什么?正如你所说的:基于PDO对象,pcre仍然是基于功能的。随着语言的发展,他们可能会在一段时间后对其进行更改。不,这是错误的,我指的是一个自动删除数字键的修改器,在多分支数组上,preg#u match_所有可能产生的结果都不是那么容易,如果您有一个像#1函数用于PHP向下兼容这样简单的解决方案,为什么要定义函数呢。它适用于所有版本。
array\u filter
解决方案依赖于常量
array\u filter\u USE\u KEY
,该项仅在PHP5.6+上可用。请参见您可以使用和使用
namedGroups()
方法。
Before Array
(
    [0] => Array
        (
            [0] => 2010-07-18
            [date] => 2010-07-18
            [1] => 2010-07-18
        )

)
After Array
(
    [date] => 2010-07-18
)
$array_filtered = array_filter($array, "is_string", ARRAY_FILTER_USE_KEY);
/**
 * @param array $array
 * @return array
 */
function dropNumericKeys(array $array)
{
    foreach ($array as $key => $value) {
        if (is_int($key)) {
            unset($array[$key]);
        }
    }
    return $array;
}
$string = "This is some text written on 2010-07-18.";
preg_match('|(?<date>\d{4}-\d{2}-\d{2})|i', $string, $arr_result);
$date = array("date" => $arr_result['date']);
unset($arr_result, $string);//delete array and string preg_match origen

print_r($date);
//or create a new:
//  $arr_result = $date;
//print_r($arr_result);
$re = '/\d+\r\n(?<start>[\d\0:]+),\d+\s--\>\s(?<end>[\d\0:]+),.*\r\nHOME.*\r\nGPS\((?<x>[\d\.]+),(?<y>[\d\.]+),(?<d>[\d\.]+)\)\sBAROMETER\:(?<h>[\d\.]+)/';

$str= file_get_contents($srtFile);
preg_match_all($re, $str, $matches, PREG_SET_ORDER, 0);
echo '<pre>';
$filtered=array_map(function ($d){
     return $array_filtered = array_filter($d, "is_string", ARRAY_FILTER_USE_KEY);
    },$matches);
var_dump($filtered);
<?php
$subject = "This is some text written on 2010-07-18.";

pattern('(?<date>\d\d\d\d-\d\d-\d\d)', 'i')->match($subject)->first(function ($match) {

    $date = $match->get('date'); 
    // 2010-07-18

    $groups = $match->namedGroups(); 
    // [
    //   'date' => '2010-07-18'
    // ]   
});