2016-05-26 38 views
2

我有一個preg_match_all功能與模式:相對簡單Preg_match_all導致502錯誤網關

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網關錯誤,而不在日誌中的任何錯誤或異常。我正在使用nginx + php-fpm(5.6.15-1 + deb.sury.org〜trusty + 1),但在php7上也是如此。

這裏是造成502錯誤網關錯誤的PHP代碼,你可以很容易地檢查它,很簡單,只是一個變量,正則表達式。

http://pastebin.com/G54Xa0as

請確保您複製的內容1:1,所有的空格,製表符等

非常STANGE事情是,你可以刪除幾乎所有的單行甚至刪除一個縮進(任何地方的任何空間)以使其工作。

我沒有更多的想法有什麼錯在這裏,我能創造這個單一的文件來證明我的問題,但不知道怎樣解決它。

+0

我無法在eval.in上重現它:https://eval.in/577522 – jeroen

+0

@jeroen正確的,令人驚訝的是,它使用PHP正常工作,只是使用'php test.php'檢查運行,它按預期工作。只有當文件通過nginx的打開用PHP-FPM(nginx的/ 1.8.0) – atay

+1

嘗試出現該問題['\ [(如果)\ S +([^ \]] * +)\]((?>(? \ [(?:end)?if \ b)。|(?R))*)\ [endif \]'](https://regex101.com/r/xA3iC8/1)甚至['\ [(如果)\ S +([^ \]] * +)\]((> [^ [] ++(:???!?\ [((?:端)如果\ b)[^ [] *)* |(ΔR))*)\ [ENDIF \]'](https://regex101.com/r/xA3iC8/2)。 –

回答

2

你的正則表達式包含負前瞻是「脾氣」的圓點圖案。但是,您未能添加結束分隔符,因此它變得相當「沉重」。

我建議增加結束符([endif]),以先行檢查:

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

demo

或者,你甚至可以展開強化貪婪令牌

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

the regex demo(但是,如果一個[可以按照[if...],它不會工作)。

此外,,你的正則表達式(if)後有空間,因爲你正在使用/x改性劑,它不被視爲一個字面上的空格,但被忽略。這就是我將其更改爲\s+的原因。