Скомпилировать регулярное выражение в PHP

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

5 ответов

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

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

PCRE Введение

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

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

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

S

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

Поток - это поток, в котором в данный момент выполняется скрипт. После первого использования скомпилированное регулярное выражение кэшируется, и в следующий раз, когда оно используется, 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 Регулярное выражение без кэширования в среднем 0,8

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

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

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

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

Другие вопросы по тегам