示例:
$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函数的类似修饰符。
答案 0 :(得分:11)
preg_match
没有任何标志或选项,它只返回命名匹配(尚未)。所以你想要的不是直接的。但是,您可以从匹配数组中删除所有带有非拟合键的项目,然后获得您想要的内容:
$matches = array_intersect_key($matches, array_flip(array('name', 'likes')));
答案 1 :(得分:8)
如何仅使用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 the elements and 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;
}
它是一个名为dropNumericKeys()
的简单PHP函数。它用于在使用命名组进行匹配的preg_match*()
运行后对匹配数组进行后处理。函数接受$array
。它迭代数组并删除/取消设置整数类型的所有键,保持字符串类型的键不变。最后,该函数返回数组&#34; now&#34;只有命名键。
注意:该函数用于PHP向下兼容性。它适用于所有版本。 array_filter
解决方案依赖于常量ARRAY_FILTER_USE_KEY
,它仅在PHP5.6 +上可用。见http://php.net/manual/de/array.constants.php#constant.array-filter-use-key
答案 2 :(得分:4)
我认为你不能让preg_*
做到这一点,但你可以用一个简单的循环来做。但我不明白为什么这些元素会造成问题。
答案 3 :(得分:3)
还可以在返回之前取消设置所有数字索引:
foreach (range(0, floor(count($arr_result) / 2)) as $index) {
unset($arr_result[$index]);
}
答案 4 :(得分:1)
与上面发布的the answer类似,我使用此代码段来获取命名参数:
$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>';
......产生这个:
Before Array
(
[0] => Array
(
[0] => 2010-07-18
[date] => 2010-07-18
[1] => 2010-07-18
)
)
After Array
(
[date] => 2010-07-18
)
答案 5 :(得分:1)
我在你的帖子中读到这些可能是未来记忆的重载等... 在这种情况下,为什么不能用 unset()来解决:
$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);
答案 6 :(得分:1)
您可以使用T-Regx并使用group()
或namedGroups()
,它们仅返回命名的捕获组。
<?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->group('date');
// 2010-07-18
$groups = $match->namedGroups();
// [
// 'date' => '2010-07-18'
// ]
});
答案 7 :(得分:0)
我使用了一些引入的代码,这是最终的代码适用于php 5.6 +:
$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);
如果您感兴趣它会从DJ文件无人机录制视频时生成的str文件中读取位置数据。
答案 8 :(得分:-1)
试试这个:
$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'];