PHP手册说明了关于PCRE" S" ({3}}
上的(模式的额外分析)修饰符S
当一个模式将被多次使用时,它是值得的 花更多时间分析它以加快所花费的时间 匹配。如果设置了此修改器,则进行此额外分析 执行。目前,研究模式仅对其有用 非锚定模式,没有一个固定的起始 字符。
因此,它的用法与应该多次使用的模式有关,它们内部没有锚点(例如^
,$
)或固定的起始字符序列,例如:像'/^abc/'
这样的模式。
但是,没有任何具体细节可以在应用此修饰符及其实际工作原理。
它是否仅适用于当前执行脚本的PHP线程,并且在执行脚本之后" cached"分析模式丢失了?或者引擎是否将模式分析存储在全局缓存中,然后使用PCRE并使用带有此修饰符标记的模式的几个PHP线程可以使用?
另外,从PCRE介绍:http://php.net/manual/en/reference.pcre.pattern.modifiers.php
注意:此扩展程序维护已编译的全局每线程缓存 正则表达式(最多4096)
如果" S" modifier仅用于每个线程,它与编译的regexp的PCRE缓存有何不同?我想存储了额外的信息,就像MySQL在索引表中的行时那样(当然在PCRE的情况下,这些附加信息存储在内存中)。
最后,但并非最不重要的是,有人经历过一个真实的用例,他/她使用过这个修饰符,你是否注意到了改进并欣赏它的好处?
感谢您的关注。
答案 0 :(得分:2)
PHP文档引用了PCRE文档的一小部分。以下是 PCRE 8.36 :
的更多细节(强调我的)如果要多次使用编译模式,则需要花费更多时间进行分析,以加快匹配所需的时间。函数
pcre_study()
将指向已编译模式的指针作为其第一个参数。如果研究模式会产生有助于加快匹配的其他信息,pcre_study()
会返回指向pcre_extra
块的指针,其中study_data
字段指向研究结果。
...
研究模式有两个作用:首先,计算匹配模式所需的主题字符串长度的下限。这并不意味着有任何匹配的字符串,但它确保没有更短的字符串匹配。该值用于通过尝试匹配短于下限的字符串来避免浪费时间。您可以通过
pcre_fullinfo()
函数找到调用程序中的值。学习模式对于没有单个固定起始字符的非锚定模式也很有用。创建可能的起始字节的位图。这样可以加快在主题中找到开始匹配的位置。(在16位模式下,位图用于小于256的16位值。在32位模式下,位图用于32位值小于256.)
请注意,在后来的PCRE版本(v10.00,也称为PCRE2)中,lib经历了大规模的重构和API重新设计。其中一个后果是在PCRE 10.00及以上版本中进行始终的学习。我不知道PHP何时会使用PCRE2,但它迟早会发生,因为PCRE 8.x从现在开始不会获得任何新功能。
的引用明确"学习"编译模式已被废除 - 现在总是如此 自动发生。 JIT编译是通过调用一个新函数来完成的, 从
pcre2_jit_compile()
成功返回后pcre2_compile()
。
至于你的第二个问题:
如果" S" modifier仅用于每个线程,它与编译的regexp的PCRE缓存有什么不同?
PCRE本身没有缓存,但是PHP维护了一个正则表达式缓存,以避免反复重新编译相同的模式,例如,如果你在循环中使用preg_
函数。 / p>