我正在研究一个相对复杂,非常大的正则表达式。它目前有41,127个字符,并且可能会增加一些,因为可能会添加其他案例。我开始在PHP中出现此错误:
preg_match_all():编译失败:偏移41123处的正则表达式太大
有没有办法增加大小限制?其他地方建议的以下设置不起作用,因为这些适用于数据大小而不是正则表达式大小:
ini_set("pcre.backtrack_limit", "100000000");
ini_set("pcre.recursion_limit", "100000000");
或者,有没有办法定义一个"子模式变量"正则表达式中的正则表达式可以在正则表达式中的各个地方重复吗? (我不是在谈论使用*
或+
重复,甚至不是重复匹配" 1")?我实际上使用的PHP变量包含在正则表达式中的几个地方重复的子模式,但是这会导致正则表达式在传递给PRCE函数之前扩展。
这是一个复杂的正则表达式,不能被更简单的关键字搜索替换为使用strpos
或this link建议的相似内容。
我宁愿避免将其拆分为|
的子表达式,并尝试分别匹配子表达式,因为缩小尺寸会适度(只有2个)或顶级|
中的3个),这将使进一步的发展复杂化。
答案 0 :(得分:6)
我不同意可能有更好方法的评论,但我会在这里回答这个问题。
您可以增加正则表达式的最大大小,但只能通过自己重新编译PHP。因此,您的代码根本不可移植,如果您使用的是预编译的二进制文件,那么您运气不佳。
那就是说,我建议找一个匹配的替代方案。
请参阅pcre_internal.h以获取评论。
PCRE将其编译代码中的偏移量保持为2字节数量 (默认情况下,始终以big-endian顺序存储)。这些用于 例如,从子模式的开头到其替代方案的链接 并结束。每个偏移使用2个字节限制了大小 编译正则表达式大约64K,几乎足够大 每一个人。但是,我收到了更大限制的请求。 出于这个原因,还要使代码更容易维护 现在处理从字节串中存储和加载偏移量 通过这里定义的宏。
宏是 由LINK_SIZE的值控制。默认为2 config.h文件,但可以在命令行上使用-D覆盖。 这是通过" configure"在Unix系统上实现的。命令。
因此,您可以从PHP源代码分发中编辑ext/pcre/pcrelib/config.h
以增加大小限制,或在编译./configure -DLINK_SIZE=4
编辑:如果您正在尝试匹配/解析HTML,我建议使用DOMDocument来解析HTML,然后遍历DOM树或构建XPATH以查找您正在寻找的内容。< / p>
答案 1 :(得分:6)
根据具体应用,有效的解决方案是:
|
拆分正则表达式,并分别处理生成的子表达式。如果正则表达式基本上是由|
分隔的众多关键字,那么使用strpos转换为strtok或循环可能是更好的&amp;更快的选择。 解决我的具体问题:根据Mario的评论,使用(?(DEFINE)...)
构造对多次重复使用的某些子表达式减少了我的正则表达式大小从41,127个字符到#34;仅#34; 4,071,这是摆脱错误“正则表达式太大”的优雅解决方案。
答案 2 :(得分:1)
让您尝试过的array_chunk拆分数组,然后在foreach()中使用preg_match_all。我使用的是完全相同的代码,并且我有一个40k +的数组,因此我通过了上述解决方案,但是它没有解决我的“编译失败:正则表达式在偏移处太大”的问题,然后将40k +数组拆分为4 1k个元素的数组,在我的preg_match_all条件下使用foreach(),瞧!有效。