【问题标题】:relatively simple Preg_match_all causes 502 Bad Gateway比较简单的 Preg_match_all 导致 502 Bad Gateway
【发布时间】:2016-05-26 11:27:04
【问题描述】:

我有一个带有模式的 preg_match_all 函数:

preg_match_all(
    '/\[(if) ([^\]]*)\]
    ((?:(?!\[if).|(?R))*?)
    \[endif\]/sx',
    $text,
    $matches
);

我猜这是很简单的模式,它寻找语法 [if condition] sometext [endif],但它也支持嵌入 ifs f.e. [if condition1] aa [if condition2] bb [endif] [endif]。我使用 s 开关将换行符视为点(因为我想让它在多行中工作)和 x 以便于阅读(但删除 x 并不能解决问题)。

它适用于我拥有的大多数输入数据,但对于某些特定输入,它会在 nginx 服务器上导致 502 Bad gateway 错误,而日志中没有任何错误或异常。我正在使用 nginx + php-fpm (5.6.15-1+deb.sury.org~trusty+1),但 php7 也是如此。

这里是导致502 Bad gateway错误的PHP代码,你可以很容易的检查它,很简单,只是一个变量和正则表达式。

http://pastebin.com/G54Xa0as

请确保您以 1:1 的比例复制内容,包括所有空格、制表符等。

非常奇怪的是,您几乎可以删除任何一行,甚至可以删除一个缩进(任何地方的任何几个空格)以使其正常工作。

我不知道这里出了什么问题,我能够创建这个文件来演示我的问题,但不知道如何解决它。

【问题讨论】:

标签: php regex whitespace preg-match-all bad-gateway


【解决方案1】:

您的正则表达式包含“缓和”点模式的负前瞻。但是,您没有为其添加结束分隔符,因此,它变得相当“沉重”。

我建议在前瞻检查中添加结束分隔符 ([endif]):

\[(if)\s+([^\]]*+)\]((?>(?!\[(?:end)?if\b).|(?R))*)\[endif\]
                             ^^^^^^^^

demo

或者,您甚至可以将经过调和的贪婪令牌展开为

\[(if)\s+([^\]]*+)\]((?>[^[]++(?:\[(?!(?:end)?if\b)[^[]*)*|(?R))*)\[endif\]

查看the regex demo(但是,如果[ 可以关注[if...],则它将不起作用)。

另外,注意您的正则表达式在(if) 之后有一个空格,并且由于您使用的是/x 修饰符,因此它不被视为文字空格,而是被忽略。这就是为什么我把它改成\s+

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-06-15
    • 2019-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-10
    • 1970-01-01
    相关资源
    最近更新 更多