Пример:
$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 )
В объекте PDO PHP есть опция, которая фильтрует результаты из базы данных, удаляя эти повторяющиеся пронумерованные значения: PDO::FETCH_ASSOC
. Но я еще не видел подобного модификатора для функций PCRE в PHP.
Я не думаю, что вы можете сделать preg_*
, но вы можете сделать это с помощью простого цикла. Но я не понимаю, почему эти элементы создают проблему.
preg_match
не имеет ни одного флага или опции, что он возвращает только имена совпадений (пока). Так что вы не хотите напрямую. Однако вы можете удалить все элементы с неподходящими ключами из массива совпадений, а затем получить то, что вы ищете:
$matches = array_intersect_key($matches, array_flip(array('name', 'likes')));
демонстрация
Как вернуть только имена групп с 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. Зафиксировать элементы и отключить, если ключ массива 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; }
с/** * @param array $array * @return array */ function dropNumericKeys(array $array) { foreach ($array as $key => $value) { if (is_int($key)) { unset($array[$key]); } } return $array; }
Его простая функция PHP с именем dropNumericKeys()
. Его для последующей обработки массива совпадений после запуска preg_match*()
с использованием названных групп для сопоставления. Функции принимают $array
. Он выполняет итерацию массива и удаляет / отключает все ключи с целым типом, оставляя ключи со строковым типом нетронутыми. Наконец, функция возвращает массив с «теперь» только с именованными ключами.
Примечание. Функция предназначена для понижающей совместимости PHP. Он работает на всех версиях. Решение array_filter
зависит от константы ARRAY_FILTER_USE_KEY
, доступной только на PHP5.6 +. См. http://php.net/manual/de/array.constants.php#constant.array-filter-use-key
Также возможно отменить все числовые индексы перед возвратом:
foreach (range(0, floor(count($arr_result) / 2)) as $index) { unset($arr_result[$index]); }
с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>';
… который производит это:
Before Array ( [0] => Array ( [0] => 2010-07-18 [date] => 2010-07-18 [1] => 2010-07-18 ) ) After Array ( [date] => 2010-07-18 )
Я прочитал в вашем сообщении, что это возможные перегрузки будущей памяти и т. Д. В этом случае, почему бы не решить проблему с 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);
Попробуй это:
$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'];