将PHP结束标记转换为注释


Convert PHP closing tag into comment

脚本中的一行在字符串中包含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