PHP中的"正则表达式太大"错误

mku*_*lon 9 php regex

我正在研究一个相对复杂,非常大的正则表达式.它目前有41,127个字符,并且可能会增加一些,因为可能会添加其他案例.我开始在PHP中出现此错误:

preg_match_all():编译失败:正则表达式在偏移量41123处太大

有没有办法增加尺寸限制?其他地方建议的以下设置不起作用,因为这些适用于数据大小而不是正则表达式大小:

ini_set("pcre.backtrack_limit", "100000000");
ini_set("pcre.recursion_limit", "100000000");
Run Code Online (Sandbox Code Playgroud)

或者,有没有办法在正则表达式中定义可以在正则表达式中的不同位置重复的"子模式变量"?(我不使用谈论重复*或者+,甚至重复匹配的"1")?我实际上使用包含子模式的PHP变量,这些子模式在正则表达式中的几个地方重复,但这导致正则表达式在传递给PRCE函数之前的扩展.

这是一个复杂的正则表达式,不能使用此链接strpos建议的简单关键字搜索替换.

我宁愿避免将其拆分为子表达式|并尝试分别匹配子表达式,因为大小的减小将是适度的(顶级只有2或3 |),这会使进一步的开发复杂化.

dre*_*010 6

我不同意有可能有更好的方法做到这一点的评论,但我会在这里回答这个问题.

您可以增加正则表达式的最大大小,但只能通过自己重新编译PHP.因此,您的代码根本不可移植,如果您使用预编译的二进制文件,则运气不佳.

也就是说,我建议找一个匹配的替代品.

有关注释,请参阅pcre_internal.h.

PCRE默认将其编译代码中的偏移量保持为2字节数量(始终以big-endian顺序存储).例如,这些用于从子模式的开头到其替代项及其结尾的链接.每个偏移量使用2个字节会将编译的正则表达式的大小限制在64K左右,这对于几乎所有人来说都足够大了.但是,我收到了更大限制的请求.出于这个原因,并且为了使代码更容易维护,现在通过这里定义的宏来处理来自字节串的偏移的存储和加载.

宏由LINK_SIZE的值控制.在config.h文件中默认为2,但可以在命令行上使用-D覆盖.这在Unix系统上通过"configure"命令自动完成.

因此,您可以ext/pcre/pcrelib/config.h从PHP源代码分发进行编辑以增加大小限制,或在编译时指定它./configure -DLINK_SIZE=4

编辑:如果您正在尝试匹配/解析HTML,我建议使用DOMDocument来解析HTML,然后遍历DOM树或构建XPATH以找到您要查找的内容.

  • 谢谢.所以要澄清:如果你想增加最大正则表达式大小,那么你必须*重新编译PHP.没有运行时选项. (3认同)

mku*_*lon 6

根据应用,有效的解决方案是:

  • 通过将DEFINE用于任何冗余子表达式缩短正则表达式(见下文).
  • 通过重新编译PHP来增加正则表达式大小的最大限制(请参阅drew010的最佳答案).虽然这可能并非在所有环境中都可用,但如果更改服务器可能会产生兼容性问题.
  • 拆分正则表达式|并分别处理生成的子表达式.如果正则表达式基本上是由关键字分隔的众多关键字|,那么使用strpos转换为strtok或循环可能是更好更快的选择.
  • 使用其他语言/正则表达式引擎,如C++/Boost,虽然我没有验证这一点.

解决我的具体问题:根据Mario的评论,使用(?(DEFINE)...)多次重复使用的一些子表达式的构造将我的正则表达式大小从41,127个字符减少到"仅"4,071,这是一个优雅的解决方案摆脱错误"正则表达式太大".

请参阅: rexegg.com上的(?(DEFINE)...)语法参考