preg_replace返回null

时间:2016-08-17 08:08:13

标签: php regex

所以我从一个字符串清理/ xss过滤器类中得到了这个,它隐藏在我正在使用的系统模块的深处。

当我把<>放入<>时,客户打来电话说"我的表单没有发布签到它"。尝试过,工作过。然后他发给我特定的文字,这是要提交和presto!我有同样的错误。

摇摆我的XDebug,当我尝试使用preg_replace从文本中删除典型的JavaScript事件处理程序时,我将问题完全发生在前面提到的字符串清理类中。

代码类似$str = preg_replace($prettyLongRegex, $replaceMent, $str); 当然,我希望$str能保持原状,如果没有匹配的话。但是,整个表达式返回NULL,有效地使我的$str成为空字符串。

热潮,文字消失了,表格没有验证,错误正在打印......

在摆弄参数的同时,我意识到文本中的另一个文本,即$str或更少的处理程序可以正常工作。正是这个确切的星座导致了我的问题。

我的问题:为什么它会返回NULL?

这是一个简单的脚本,通过打印NULL

来显示问题
<?php

$str = <<< EOF
Aim

To compare the clinical evolution of >70% asymtomatic in-stent  restenosis  in superficial femoral artery. (SFA) treated with endovascular procedure or conservative treatment.

Methods

Historical cohort  study was performed in patients with femoral artery stent with an asymptomatic  in-stent restenosis of 70-99%. Two groups: Conservative managment vs endovascular treatment.

In both groups we compared: Limb salvage  and critical ischemia or limited claudication free survival rates ( <250m) , from initial stent  treatment until  the appearance of critical ischemia o major amputation  ( Log-Rank, Kaplan Meier).

Primary permeability and  assisted primary permeability  were analized.


Results

From January 2010-December 2015, twenty three  >70%  in-stent restenosis were diagnosed  in 20 patients  with an average age of 78 years old (SD 9,6). Average follow-up was of  30,1 months. 12 patients (52,2%) received medical  (Aspirin and Statins) and  endovascular treatment.  11 patients (47,8%) received only medical treatment without  an endovascular procedure.

No difference were seen in limb salvage.

Critical ischemia  or limited claudication free survival rates were higher in the conservative treatment group vs  endovascular group.  (P=0,031)

Primary permeability  was 14,2 months ( IC 8,2-20.2). Assisted primary permeability, 65,5 months ( IC 57,4-77,5).

Conclusions

In our experience treatment of  severe asymtomatic lesions of  in-stent stensosis in SFA does not reduce the risk of amputation, critical ischaemia o limitant claudication. In asymptomatic patients, conservative treatment could be a good option, without increasing the risk in amputation and critical ischema.
EOF;

$str = preg_replace('#(<[^>]+.*?)(onabort|onactivate|onafterprint|onafterupdate|onbeforeactivate|onbeforecopy|onbeforecut|onbeforedeactivate|onbeforeeditfocus|onbeforepaste|onbeforeprint|
        onbeforeunload|onbeforeupdate|onblur|onbounce|oncanplay|oncanplaythrough|oncellchange|onchange|
        onclick|oncontextmenu|oncontrolselect|oncopy|oncuechange|oncut|ondataavailable|ondatasetchanged|
        ondatasetcomplete|ondblclick|ondeactivate|ondrag|ondragend|ondragenter|ondragleave|ondragover|
        ondragstart|ondrop|ondurationchange|onemptied|onended|onerror|onerrorupdate|onfilterchange|
        onfinish|onfocus|onfocusin|onfocusout|onformchange|onforminput|onhashchange|onhelp|oninput|oninvalid,|onkeydown|
        onkeypress|onkeyup|onlayoutcomplete|onload|onloadeddata|onloadedmetadata|onloadstart|
        onlosecapture|onmessage|onmousedown|onmouseenter|onmouseleave|onmousemove|onmouseout|
        onmouseover|onmouseup|onmousewheel|onmove|onmoveend|onmovestart|onoffline|ononline|
        onpagehide|onpageshow|onpaste|onpause|onplay|onplaying|onpopstate|onprogress|
        onpropertychange|onratechange|onreadystatechange|onredo|onreset|onresize|onresizeend|
        onresizestart|onrowenter|onrowexit|onrowsdelete|onrowsinserted|onscroll|onseeked|onseeking|
        onselect|onselectionchange|onselectstart|onshow|onstalled|onstart|onstop|onstorage|onsubmit|
        onsuspend|ontimeupdate|onundo|onunload|onvolumechange|onwaiting)[^>]*>#iU',"\\1>",$str);

var_dump($str);

我的系统是OSX 10.11.4和

PHP 5.6.17 (cli) (built: Jan  8 2016 10:27:48)
Copyright (c) 1997-2015 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2015 Zend Technologies
with Zend OPcache v7.0.6-dev, Copyright (c) 1999-2015, by Zend Technologies
with Xdebug v2.3.3, Copyright (c) 2002-2015, by Derick Rethans

1 个答案:

答案 0 :(得分:5)

请参阅preg_replace reference

  

如果找到匹配项,将返回新主题,否则主题将保持不变或 NULL 如果发生错误。

错误为catastrophic backtracking - 请参阅your regex demo

要解决此问题,您需要在开始时删除[^>]+或保留[^>]+并删除.*?(取决于您需要匹配的内容)。关键是[^>]+.*?可以在同一位置匹配,因为模式后面跟着一个巨大的交替组(其中所有选项都以相同的on子字符串开头,让所有这些字符串都放在一起匹配在同一位置),这会产生大量可能的变化,正则表达式引擎必须在承认失败之前检查 - 导致灾难性的回溯。

如果将on放在(...)之外,您还可以大大提高模式:

(<[^>]+)on(abort|activate|afterprint|afterupdate|beforeactivate|beforecopy|beforecut|beforedeactivate|beforeeditfocus|beforepaste|beforeprint|
        onbeforeunload|beforeupdate|blur|bounce|canplay|canplaythrough|cellchange|change|
        onclick|contextmenu|controlselect|copy|cuechange|cut|dataavailable|datasetchanged|
        ondatasetcomplete|dblclick|deactivate|drag|dragend|dragenter|dragleave|dragover|
        ondragstart|drop|durationchange|emptied|ended|error|errorupdate|filterchange|
        onfinish|focus|focusin|focusout|formchange|forminput|hashchange|help|input|invalid,|keydown|
        onkeypress|keyup|layoutcomplete|load|loadeddata|loadedmetadata|loadstart|
        onlosecapture|message|mousedown|mouseenter|mouseleave|mousemove|mouseout|
        onmouseover|mouseup|mousewheel|move|moveend|movestart|offline|online|
        onpagehide|pageshow|paste|pause|play|playing|popstate|progress|
        onpropertychange|ratechange|readystatechange|redo|reset|resize|resizeend|
        onresizestart|rowenter|rowexit|rowsdelete|rowsinserted|scroll|seeked|seeking|
        onselect|selectionchange|selectstart|show|stalled|start|stop|storage|submit|
        onsuspend|timeupdate|undo|unload|volumechange|waiting)[^>]*>

请参阅regex demo

注意:如果您需要与第一个on...匹配,请将(<[^>]+)转换为惰性子模式 - (<[^>]+?),也许您也希望在on之前添加字边界:(<[^>]+?)\bon