Вопрос на засыпку: как упорядочить результаты из нескольких регулярных выражений - PullRequest
2 голосов
/ 04 марта 2009

В настоящее время я использую 3 различных регулярных выражения в одном preg_match, используя знак или | отделить их. Это работает отлично. Однако первый и второй регулярные выражения имеют одинаковый тип вывода. например [0] Исходный текст [1] Число Количество [2] Имя - однако последнее, так как в нем используется другое расположение исходного текста, приводит к: [0] Исходный текст [1] Имя [2] Количество Количество.

    preg_match('/^Guo (\d+) Cars @(\w+)|^AV (\d+) Cars @(\w+)|^@(\w+) (\d+) [#]?av/i', $source, $output);

Поскольку Name может быть числовым, я не могу выполнить простую проверку, чтобы увидеть, является ли он числовым. Есть ли способ, которым я могу либо изменить порядок в регулярном выражении, либо определить, какое регулярное выражение тоже соответствует Скорость здесь важна, поэтому я не хотел использовать 3 отдельных оператора preg_match (и многое другое).

Ответы [ 3 ]

3 голосов
/ 04 марта 2009

Три отдельных регулярных выражения не должны быть медленнее. Одно большое утверждение будет означать много возврата для механизма регулярных выражений. Ключом к оптимизации регулярных выражений является сбой движка как можно скорее. Вы делали какие-то тесты, вытягивая их из квартиры?

В вашем случае вы можете использовать именованные захваты PCRE (?<name>match something here) и заменить на ${name} вместо \1. Я не уверен на 100%, что это работает для preg_replace. Я знаю, что preg_match правильно хранит именованные захваты наверняка.

PCRE необходимо скомпилировать с опцией PCRE_DUPNAMES, чтобы это было полезно в вашем случае (как в случае Роборга). Я не уверен, что скомпилированный PHP-файл PCRE DLL имеет эту опцию.

3 голосов
/ 04 марта 2009

Вы можете использовать именованные группы захвата:

preg_match('/^Guo (?P<number_amount>\d+) Cars @(?P<name>\w+)|^AV (?P<number_amount>\d+) Cars @(?P<name>\w+)|^@(?P<name>\w+) (?P<number_amount>\d+) [#]?av/i', $source, $output);
0 голосов
/ 04 марта 2009

Я не знаю, с какой версии PCRE поддерживает синтаксис дубликатов номеров подшаблонов (?| … ). Но попробуйте это регулярное выражение:

/^(?|Guo (\d+) Cars @(\w+)|AV (\d+) Cars @(\w+)|@(\w+) (\d+) #?av)/i

Итак:

$source = '@abc 123 av';
preg_match('/^(?|Guo (\\d+) Cars @(\\w+)|AV (\\d+) Cars @(\\w+)|@(\\w+) (\\d+) #?av)/i', $source, $output);
var_dump($output);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...