【发布时间】:2010-09-17 14:48:48
【问题描述】:
PHP 中有没有一种方法可以编译正则表达式,这样就可以在不重复编译过程的情况下将其与多个字符串进行比较?其他主要语言可以做到这一点——Java、C#、Python、Javascript 等。
【问题讨论】:
PHP 中有没有一种方法可以编译正则表达式,这样就可以在不重复编译过程的情况下将其与多个字符串进行比较?其他主要语言可以做到这一点——Java、C#、Python、Javascript 等。
【问题讨论】:
Perl 兼容的正则表达式库可能已经针对您的用例进行了优化,而无需像其他语言那样提供 Regex 类:
此扩展维护已编译正则表达式的全局每线程缓存(最多 4096 个)。
这就是Imran 描述的研究修饰符如何在调用之间存储编译后的表达式。
【讨论】:
preg 正则表达式可以使用大写的 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);
带有缓存 avg 0.1 的正则表达式 没有缓存的正则表达式平均 0.8
缓存正则表达式使其速度提高 8 倍!
【讨论】:
$i,并且在该位置始终为0
正如另一位评论者已经说过的那样,PCRE 正则表达式已经编译,而您不必专门引用它们,PCRE 会保留一个由您提供的原始字符串索引的内部哈希。
【讨论】:
我不肯定你可以。如果你查看Mastering Regular Expressions,一些 PHP 特定的优化技术将在第 10 章:PHP 中讨论。特别是使用 S 模式修饰符使正则表达式引擎在应用正则表达式之前对其进行“研究”。根据您的模式和文本,这可能会提高您的速度。
编辑:您可以使用books.google.com查看本书的内容。
【讨论】: