PCRE PHP具体的"S"(模式的额外分析)修饰符的用法和实用程序示例?

ton*_*nix 6 php regex caching pcre

PHP手册在http://php.net/manual/en/reference.pcre.pattern.modifiers.php上说明了关于PCRE的"S"(模式的额外分析)修饰符的以下内容

小号

当一个模式将被多次使用时,值得花更多时间分析它以加快匹配所需的时间.如果设置了此修改器,则执行此额外分析.目前,研究模式仅对于没有单个固定起始字符的非锚定模式有用.

因此它的用法与应该多次使用的模式有关,没有锚点在它们内部(例如^,$)或固定的起始字符序列,例如在类似的模式中'/^abc/'.

但是没有任何具体细节,例如应用此修饰符以及它实际如何工作.

它是否仅适用于当前执行脚本的PHP线程,并且在执行脚本后,模式的"缓存"分析会丢失?或者引擎是否将模式的分析存储在全局缓存中,然后使用PCRE并使用带有此修饰符的模式的几个PHP线程可以使用该缓存?

另外,从PCRE介绍:http://php.net/manual/en/intro.pcre.php

注意:此扩展维护已编译正则表达式的全局每线程缓存(最多4096)

如果仅为每个线程使用"S"修饰符,它与编译的正则表达式的PCRE高速缓存有何不同?我想存储了额外的信息,就像MySQL在索引表中的行时那样(当然在PCRE的情况下,这些附加信息存储在内存中).

最后,但并非最不重要的是,有人经历过一个真实的用例,他/她使用过这个修饰符,你是否注意到了改进并欣赏它的好处?

感谢您的关注.

Luc*_*ski 5

PHP 文档引用了 PCRE 文档的一小部分。以下是PCRE 8.36的更多详细信息(重点是我的):

如果要多次使用编译的模式,则值得花费更多时间对其进行分析,以加快匹配所需的时间。该函数pcre_study()将指向已编译模式的指针作为其第一个参数。如果研究模式产生有助于加速匹配的附加信息,pcre_study()则返回指向块的指针pcre_extra,其中study_data字段指向研究结果。

...

研究模式有两件事:首先,计算匹配该模式所需的主题字符串长度的下限。这并不意味着有任何该长度的字符串匹配,但它确实保证没有更短的字符串匹配。该值用于避免尝试匹配比下限短的字符串而浪费时间。您可以通过该函数找出调用程序中的值pcre_fullinfo()

研究模式对于没有单个固定起始字符的非锚定模式也很有用。创建可能的起始字节的位图。这可以加快在主题中找到开始匹配的位置的速度。(在 16 位模式下,位图用于小于 256 的 16 位值。在 32 位模式下,位图用于小于 256 的 32 位值。)

请注意,在后来的 PCRE 版本(v10.00,也称为 PCRE2)中,该库经历了大规模的重构和 API 重新设计。后果之一是学习总是在 PCRE 10.00 及以上进行。我不知道 PHP 何时会使用 PCRE2,但这迟早会发生,因为从现在开始 PCRE 8.x 将不会获得任何新功能。

以下是PCRE2 发布公告中的引用:

对已编译模式的显式“研究”已被废除 - 现在它总是自动发生。pcre2_jit_compile()JIT 编译是在成功返回后通过调用新函数来完成的 pcre2_compile()


至于你的第二个问题:

如果“S”修饰符仅在每个线程中使用,它与已编译正则表达式的 PCRE 缓存有何不同?

PCRE 本身没有缓存,但 PHP 维护了正则表达式的缓存,以避免一遍又一遍地重新编译相同的模式,例如在preg_循环内使用函数的情况下。