将PHP结束标签转换为注释
我的脚本中的一行包含一个string内的PHP结束标记。 在正常的操作下,这不会造成问题,但我需要注释掉这一行。
我试图用//
, /*
*/
和#
注释掉这一行,但是它们都没有工作,parsing器认为closures标记是一个实际的结束标记。
这是问题的线路:
$string = preg_replace('#<br\s*/?>(?:\s*<br\s*/?>)+#i', '<br />', $string); // ^^ ^^
我可以做些什么来评论以上的线?
使用一个技巧:连接来自两个部分的string。 这样,结束标签被切成两半,不再是有效的结束标签。 '?>' --> '?'.'>'
在你的代码中:
$string = preg_replace('#<br\s*/?'.'>(?:\s*<br\s*/?'.'>)+#i', '<br />', $string);
这将使/ /评论工作。
对于/* */
注释的工作,你必须分割*/
序列:
$string = preg_replace('#<br\s*'.'/?'.'>(?:\s*<br\s*'.'/?'.'>)+#i', '<br />', $string);
请记住,有时候,即使整体不只是它的部分总和 – 但是贪婪是不好的,有些时候你最好less离开。 🙂
最简单的方法
创build一个单独的variables来保存你的正则expression式; 这样你可以简单地注释掉preg_replace()
语句:
$re = '#<br\s*/?>(?:\s*<br\s*/?>)+#i'; // $string = preg_replace($re, '<br />', $string);
修复使用字符类
为了修正行注释,你可以通过在一个字符类里面放置>
来分解:
$string = preg_replace('#<br\s*/?[>](?:\s*<br\s*/?[>])+#i', '<br />', $string); ^ ^ ^ ^
要修复块注释,可以将其应用于/
:
$string = preg_replace('#<br\s*[/]?>(?:\s*<br\s*[/]?>)+#i', '<br />', $string); ^ ^ ^ ^
要解决这两种评论风格,你可以把/
和 >
放在他们自己的angular色类中。
使用/x
修饰符修复
x
修饰符 – 又名PCRE_EXTENDED
– 忽略正则expression式中的空格和换行符(除非它们出现在字符类中); 这使得可以添加空格来分离有问题的字符。 要修复两种评论风格:
$string = preg_replace('#<br\s* /? >(?:\s*<br\s* /? >)+#ix', '<br />', $string); ^ ^ ^ ^
为什么你的尝试不起作用:
// $string = preg_replace('#<br\s*/?>(?:\s*<br\s*/?>)+#i',... ^ doesn't work due to ?> ending php /* $string = preg_replace('#<br\s*/?>(?:\s*<br\s*/?>)+#i',... */ ^ doesn't work due to */ closing comment
什么工作:
/* $string = preg_replace('#<br\s*[/]?>(?:\s*<br\s*[/]?>)+#i',... */ ^ ^ ^ ^ // $string = preg_replace('#<br\s*/?[>](?:\s*<br\s*/?[>])+#i',... ^ ^ ^ ^
进一步…
以上之后,你应该可以使用/*
来注释掉该行。 如果你保持?>
完整, //
不可能注释掉整行。 下面的文本可能是html,这是PHP解释器控制之外的 ,所以这是行不通的。
从文档:
“单行”评论样式只对该行的末尾或当前的PHP代码块进行注释,以先到者为准。 这意味着HTML代码在// …?>或#…?>之后将被打印出来:?> PHP模式退出并返回到HTML模式,并且//或#不能影响该模式。
另一个想法:转义>
(和/
,如果你想使用/*...*/
注释):
$string = preg_replace('#<br\s*\/?\>(?:\s*<br\s*\/?\>)+#i', '<br />', $string);
正则expression式引擎会忽略“不必要的”转义,但在这种情况下(由于其他答案中概述的原因)非常有用。
为什么要使用复杂的,难以阅读的“技巧”来解决这个问题呢?
?
只是方便的量词捷径,所以
只要使用量词{0,1}
的长版本 ,意思是“最小0最大1次出现”:
$string = preg_replace('#<br\s*/{0,1}>(?:\s*<br\s*/{0,1}>)+#i', '<br />', $string);
其他一些值得添加到RegEx技巧书中的方法 :
首先,您可以将您的RegEx压缩到: /(<br\s*/?>)+/i
/?> /(<br\s*/?>)+/i
并用<br />
replace(不需要使用向前的方式来加载RegExP),并且您最终会selectXHMTL越线。
其他方法来修改您的正则expression式,所以它不会旅行*/
结束评论或?>
结束脚本:
- 使用所有格量词 :
#(<br\s*+/?+>)+#i
– 如果您发现空格匹配的数量与\s*+
基本相同,请保留它,对于/?+
发现一个斜杠保持它! - 在捕获组中包含
\s*
和/*
=#(<br(\s*)(/?)>)+#i
现场演示: http : //codepad.viper-7.com/YjqUbi
而且,由于我们把所有格行为最快的RegEx也绕过了评论问题: #(<br\s*+/?+>)++#i
至于在棘手的情况下评论
当您无法更改代码或已经使用多行注释时:
1.使用nowdoc :
$string='Hello<br>World<br><br />World<br><br><br>Word!'; <<<'comment' $string = preg_replace('#(<br\s*/?>)+#i', '<br />', $string); comment;
现场代码: http : //codepad.viper-7.com/22uOtV
注意: nowdoc类似于heredoc,但它不parsing内容,并且必须以'
单引号'
开始分隔符( 请注意, 结尾分隔符不能被构造 ,必须跟在后面;
并且新行 ! )
2.用goto跳过代码:
$string='Hello<br>World<br><br />World<br><br><br>Word!'; goto landing; $string = preg_replace('#(<br\s*/?>)+#i', '<br />', $string); landing:
现场示例: http : //codepad.viper-7.com/UfqrIQ
3.用if(false)
或if(0)
跳过代码:
$string='Hello<br>World<br><br />World<br><br><br>Word!'; if(0){ $string = preg_replace('#(<br\s*/?>)+#i', '<br />', $string); }
testing: http : //codepad.viper-7.com/wDg5H5