在 PHP 中编译正则表达式
Posted
技术标签:
【中文标题】在 PHP 中编译正则表达式【英文标题】:Compile regex in PHP 【发布时间】:2010-09-17 14:48:48 【问题描述】:php 中有没有一种方法可以编译正则表达式,这样就可以在不重复编译过程的情况下将其与多个字符串进行比较?其他主要语言可以做到这一点——Java、C#、Python、javascript 等。
【问题讨论】:
【参考方案1】:Perl 兼容的正则表达式库可能已经针对您的用例进行了优化,而无需像其他语言那样提供 Regex 类:
此扩展维护已编译正则表达式的全局每线程缓存(最多 4096 个)。
PCRE Introduction
这就是Imran 描述的研究修饰符如何在调用之间存储编译后的表达式。
【讨论】:
我可以增加每线程缓存的大小吗?4096是什么意思 我认为这意味着 4096 个已编译的正则表达式。【参考方案2】:preg 正则表达式可以使用大写的 S(study)修饰符,这可能是您正在寻找的东西。
http://www.php.net/manual/en/reference.pcre.pattern.modifiers.php
S
当一个模式要被多次使用时,值得花费 更多的时间来分析它,以便 加快匹配所需的时间。 如果设置了这个修饰符,那么这个 进行额外的分析。在 目前,研究模式很有用 仅适用于非锚定模式 没有一个固定的起点 字符。
【讨论】:
OP 问题的答案是不需要在 PHP 中预编译正则表达式,因为正如 1stvamp 所指出的,已编译的正则表达式会自动缓存。 'S' 修饰符是一个单独的问题。 此答案已添加到 Stack Overflow Regular Expression FAQ 的“修饰符”下。【参考方案3】:线程是脚本当前运行的线程。第一次使用后,编译的正则表达式被缓存,下次使用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 倍!
【讨论】:
测试为 NUL!因为:您在第二个示例中连接了 3 个字符串(没有缓存),而在第一个示例中,模式中不存在“变量”$i
,并且在该位置始终为0
测试仍然合理有效。通过在第一个测试中将字符串 "$j-$y" 与 $j = 37 和 $y = 5 连接,在第二个测试中连接字符串 "$i-$x"(-$x 是通过testTimes),我得到 0.0112 和 0.0431 的时间。在第二次测试中使用“$i-$y”得到相同的 0.0431,这意味着缓存的大小确实小于 10000。因此,我的实际加速比快 4 倍(不是 8 倍)。【参考方案4】:
正如另一位评论者已经说过的那样,PCRE 正则表达式已经编译,而您不必专门引用它们,PCRE 会保留一个由您提供的原始字符串索引的内部哈希。
【讨论】:
【参考方案5】:我不肯定你可以。如果你查看Mastering Regular Expressions,一些 PHP 特定的优化技术将在第 10 章:PHP 中讨论。特别是使用 S 模式修饰符使正则表达式引擎在应用正则表达式之前对其进行“研究”。根据您的模式和文本,这可能会提高您的速度。
编辑:您可以使用books.google.com查看本书的内容。
【讨论】:
每一个使用正则表达式的开发者都应该阅读这本书!!提高效率所需的所有技术都在本书中。以上是关于在 PHP 中编译正则表达式的主要内容,如果未能解决你的问题,请参考以下文章