Скомпилировать регулярное выражение в PHP - PullRequest
59 голосов
/ 16 октября 2008

Есть ли в PHP способ скомпилировать регулярное выражение, чтобы его можно было сравнить с несколькими строками без повторения процесса компиляции? Другие основные языки могут сделать это - Java, C #, Python, Javascript и т. Д.

Ответы [ 5 ]

43 голосов
/ 17 октября 2008

Библиотека регулярных выражений, совместимая с Perl, возможно, уже оптимизирована для вашего случая использования без предоставления класса Regex, как это делают другие языки:

Это расширение поддерживает глобальный кэш каждого скомпилированного регулярного выражения (до 4096).

PCRE Введение

Вот как модификатор исследования, описанный Имран , может хранить скомпилированное выражение между вызовами.

18 голосов
/ 16 октября 2008

регулярные выражения preg могут использовать модификатор S (study) в верхнем регистре, что, вероятно, то, что вы ищете.

http://www.php.net/manual/en/reference.pcre.pattern.modifiers.php

S

Когда шаблон будет использоваться несколько раз, стоит потратить больше времени на его анализ, чтобы ускорить время, необходимое для сопоставления. Если этот модификатор установлен, то этот проводится дополнительный анализ. В настоящее, изучение шаблона полезно только для не закрепленных шаблонов, которые делают не имеют ни одного фиксированного пуска характер.

12 голосов
/ 19 августа 2011

Поток - это поток, в котором в данный момент выполняется скрипт. После первого использования скомпилированное регулярное выражение кэшируется, и при следующем использовании PHP не компилирует его снова.

Простой тест:

<?php

function microtime_float() {
    list($usec, $sec) = explode(" ", microtime());
    return ((float)$usec + (float)$sec);
}

// test string
$text='The big brown <b>fox</b> jumped over a lazy <b>cat</b>';
$testTimes=10;


$avg=0;
for ($x=0; $x<$testTimes; $x++)
{
    $start=microtime_float();
    for ($i=0; $i<10000; $i++) {
        preg_match_all('/<b>(.*)<\/b>0?/', $text, $m);
    }
    $end=microtime_float();
    $avg += (float)$end-$start;
}

echo 'Regexp with caching avg '.($avg/$testTimes);

// regexp without caching
$avg=0;
for ($x=0; $x<$testTimes; $x++)
{
    $start=microtime_float();
    for ($i=0; $i<10000; $i++) {
        $pattern='/<b>(.*)<\/b>'.$i.'?/';
        preg_match_all($pattern, $text, $m);
    }
    $end=microtime_float();
    $avg += (float)$end-$start;
}

echo '<br/>Regexp without caching avg '.($avg/$testTimes);

регулярное выражение с кэшированием, средняя 0,1 Регулярное выражение без кеширования avg 0.8

Кэширование регулярного выражения делает его в 8 раз быстрее!

7 голосов
/ 17 декабря 2008

Как уже сказал другой комментатор, регулярные выражения PCRE уже скомпилированы без необходимости специально ссылаться на них как таковые, PCRE хранит внутренний хеш, проиндексированный с помощью предоставленной вами исходной строки.

4 голосов
/ 16 октября 2008

Я не уверен, что вы можете. Если вы посмотрите Освоение регулярных выражений , некоторые специфические методы PHP обсуждаются в главе 10: PHP. В частности, использование модификатора S-шаблона для того, чтобы механизм регулярных выражений «изучал» регулярное выражение до его применения. В зависимости от вашего шаблона и вашего текста, это может дать вам некоторые улучшения скорости.

Редактировать : вы можете просмотреть содержание книги, используя books.google.com .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...