Подтвердить что ты не робот

Увеличивает ли порядок предварительного массива 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, обязательно являются числовыми?

4b9b3361

Ответ 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 просто сравнивают их без какого-либо преобразования. Таким образом, это в конечном счете будет зависеть от того, что происходит быстрее: слепое преобразование в двойное или выполнение проверки типа.