Увеличивает ли порядок предварительного массива preg_offset_capture * гарантированный *?
Я не смог найти авторитетного ответа на этот вопрос, хотя я на 99.9% уверен, что это правда. Такие вещи, как принятый ответ, чтобы полагаться на то, что это правда, поскольку я ожидаю, что много другого кода. Но может ли кто-нибудь, кто действительно что-то знает о preg_match_all
(а не наблюдением, а указанным требованием или указанным алгоритмом), подтверждает, что это гарантированное поведение? Я не могу его извлечь из документации.
Мой пример использования очень прост:
preg_match_all("/$regexp/", $content, $matches, PREG_OFFSET_CAPTURE);
И я знаю, что $regexp
не содержит подматрицы, поэтому в документации мне сообщается, что $matches[0]
будет массивом из 2-элементных массивов, где каждый подмассиво имеет элементы с числовым ключом 0, содержащим строка, соответствующая шаблону, и числовой ключ 1, содержащий смещение в $content
, в котором произошло совпадение. И хотя кажется разумным, что элементы массива будут упорядочены путем увеличения смещения, я не вижу, где это требуется, так что это будет ошибка, если бы это было не так. Хотя я не могу себе представить, как это можно было бы сделать для полезного эффекта, возможно, есть способ реализовать preg_match_all
с несколькими потоками, которые добавляют свои частичные результаты, не сливаясь в полностью отсортированный порядок.
В моем конкретном случае я забочусь только о смещениях, а не о строках, которые были сопоставлены, но важно, чтобы смещения увеличивались. Итак, с менталитетом ремней и подтяжек я закодировал:
preg_match_all("/$regexp/", $content, $matches, PREG_OFFSET_CAPTURE);
$offsets = array();
foreach ($matches as $match) {
$offsets[] = $match[1];
}
sort($offsets);
Иначе говоря, является ли окончательная sort($offsets)
гарантированной потерей циклов?
И если это не вызовет у меня проблемы с заданием связанного, но потенциально отдельного вопроса, если бы этот вид был потенциально полезным, было бы более/менее/одинаково эффективным использовать флаг SORT_REGULAR
по умолчанию, как показано, или указать явно SORT_NUMERIC
, учитывая, что смещения, создаваемые внутри preg_match_all
, обязательно являются числовыми?
Ответы
Ответ 1
Относительно вашего вопроса о порядке смещения строки:
Полные совпадения всегда должны быть в порядке возрастания строки. PHP реализует глобальное соответствие с циклом, который устанавливает start_offset
в конце последнего полного совпадения до конца строки темы. То есть, он находит первое совпадение, затем второе, затем
третий и т.д.
Если вы хотите проверить, что я не ужасно неправильно читаю исходный код (или отсутствует что-то существенное), вы можете посмотреть на функцию
php_pcre_match_impl
в ext/pcre/php_pcre.c
. preg_match_all
устанавливает глобальный параметр в 1. То, что в меня было связано, было комментарием в конце
цикла do while для global
:
/*Advance to the position right after the last full match*/
start_offset = offsets[1];
Если установлено глобальное значение, цикл повторяется с новым смещением и pcre_exec
снова вызывается с ним.
Относительно вашего SORT_NUMERIC вопроса:
Трудно сказать. Настройка SORT_NUMERIC
делает сортировку numeric_compare_function
для сравнения элементов, где SORT_REGULAR
использует compare_function
.
compare_function
выполняет проверку типа, а затем решает, что делать для сравнения оттуда, тогда как numeric_compare_function
просто слепо преобразует оба в
double
s. Поскольку оба LONGs compare_function
просто сравнивают их без какого-либо преобразования. Таким образом, это в конечном счете будет зависеть от того, что происходит быстрее: слепое преобразование в двойное или выполнение проверки типа.