脚本中的一行在字符串中包含PHP结束标记。在正常操作下,这不会引起问题,但是我需要注释掉这行。
我试图用//
, /*
, */
和#
注释出这行,但它们都不起作用,解析器认为结束标记是实际的结束标记。
这是有问题的行:
$string = preg_replace('#<br's*/?>(?:'s*<br's*/?>)+#i', '<br />', $string);
// ^^ ^^
我怎么做才能注释掉上面的行?
使用一个技巧:将两段字符串连接起来。这样,结束标记被切成两半,并且不再是有效的结束标记。'?>' --> '?'.'>'
在你的代码中:
$string = preg_replace('#<br's*/?'.'>(?:'s*<br's*/?'.'>)+#i', '<br />', $string);
这将使//
注释工作。
对于/* */
注释工作,您必须分割*/
序列:
$string = preg_replace('#<br's*'.'/?'.'>(?:'s*<br's*'.'/?'.'>)+#i', '<br />', $string);
记住,有时候,即使整体大于部分的总和——但是贪婪是不好的,有时候你最好让少一些。:)
最简单的方法
创建一个单独的变量来保存正则表达式;这样,您可以简单地注释掉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);
^ ^ ^ ^
要修复这两种注释样式,您可以将/
和 >
放在它们自己的字符类中。
/x
修饰符
x
修饰符——又名PCRE_EXTENDED
——忽略正则表达式中的空格和换行符(除非它们出现在字符类中);这使得添加空格来分隔有问题的字符成为可能。修复两个注释样式:
$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解释器的控制之外的,因此不能工作。
来自文档:
"one-line"注释样式只注释到行尾或当前的PHP代码块,以先到的为准。这意味着//…后的HTML代码?>或#…?>将被印刷:?>爆发//或#不能影响PHP模式并返回HTML模式
。
另一个想法:转义>
(以及/
,如果您想使用/*...*/
注释):
$string = preg_replace('#<br's*'/?'>(?:'s*<br's*'/?'>)+#i', '<br />', $string);
一个"不必要的"转义被regex引擎忽略,但在这种情况下是有用的(原因在其他答案中概述)。
为什么要使用复杂的、难以阅读的"技巧"来解决问题呢?
?
只是一个方便的量词快捷方式,所以
仅使用长版本的量词{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 />
(不需要给RegExP增加查找头的负担),您将始终以您选择的xhtml换行符结束。
其他修改RegEx的方法,使它不会绊倒*/
结束注释或?>
结束脚本:
- 使用所有格量词:
#(<br's*+/?+>)+#i
-这基本上意味着对于's*+
,如果你发现空白匹配并保留它,对于/?+
,如果你发现斜杠保留它! - 将
's*
和/*
放入捕获组=>#(<br('s*)(/?)>)+#i
现场演示:http://codepad.viper-7.com/YjqUbi
由于我们学习了占有行为,最快的RegEx也绕过了注释问题是: #(<br's*+/?+>)++#i
解释demo
对于复杂情况下的注释
当你不能改变代码,或者已经使用了多行注释和:
1。使用nowdoc:
$string='Hello<br>World<br><br />World<br><br><br>Word!';
<<<'comment'
$string = preg_replace('#(<br's*/?>)+#i', '<br />', $string);
comment;
Live code: http://codepad.viper-7.com/22uOtV
注意:nowdoc类似于heredoc,但它不解析内容,并且必须将起始分隔符括在'
单引号'
中(注意结束分隔符不能被识别,必须后跟;
和新行 !)
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);
}
测试:http://codepad.viper - 7. - com/wdg5h5