【问题标题】:PHP regex not working, despite successfully matching in regex101尽管在 regex101 中成功匹配,但 PHP 正则表达式不起作用
【发布时间】:2019-11-08 01:22:29
【问题描述】:

我遇到了最奇怪的问题。我试过在这里参考其他类似的答案,但似乎没有一个能解决我的问题。

我在 PHP 中有以下正则表达式

/if\s+(?:(.*?)\s*==\s*(?:UrlStatus|DeadURL)|in_array\s*\((?:UrlStatus|DeadURL),\s*(.*?)\s*\))\s*then\s+local\s+arch_text\s+=\s+cfg.messages\['archived'\];(?:(?:\n|.)*?if\s+(?:(.*?)\s*==\s*(?:UrlStatus|DeadURL)|in_array\s*\((?:UrlStatus|DeadURL),\s*(.*?)\s*\))\s*then\s+Archived = sepc \.\.)?/im

我知道这是一个混乱的正则表达式,它应该从不同位置的各种版本的模块中解析代码。它在 regex101 中完美运行,但 preg_match 返回 false,表示发生错误。您看到的正则表达式是直接从 var_dump 中提取的。从 var_dump 中提取的还有正在测试的字符串。我在下面包含了应该与之匹配的摘录。

    if is_set(ArchiveURL) then
        if not is_set(ArchiveDate) then
            ArchiveDate = seterror('archive_missing_date');
        end
        if "no" == DeadURL then
            local arch_text = cfg.messages['archived'];
            if sepc ~= "." then arch_text = arch_text:lower() end
            Archived = sepc .. " " .. substitute( ```

In the full block of text it takes 81,095 steps to match.  
Could it have something to do with that?

【问题讨论】:

  • 你看过preg_last_error()的输出了吗?
  • 你听说过我们的救世主,正则表达式/x可读性标志吗?
  • @Nick 它似乎返回 PREG_JIT_STACKLIMIT_ERROR。虽然我不确定如何解决它。
  • @Cyber​​power678 在常量定义 page 上有一个关于禁用 JIT 的注释
  • @Nick Stackoverflow 是一个美丽的地方。 $old = ini_set('pcre.jit', false );成功了,现在它匹配了。 :D

标签: php regex pcre


【解决方案1】:

从 preg_last_error() 读取,它返回 6,它映射到常量 PREG_JIT_STACKLIMIT_ERROR。

PHP 7 对 preg_match 使用 JIT 编译器,具有较小的堆栈大小限制。禁用它允许 preg_match 完成它的工作。

这可以在 php.ini 文件中完成,或者在脚本中使用 ini_set( 'pcre.jit', false ); 即时完成

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多