将 PHP 结束标记转换为注释

我的脚本中的一行包含一个字符串内的 PHP 结束标记。在正常操作下,这不会引起问题,但是我需要注释掉这一行。

我已经尝试用 ///*#注释掉这一行,但它们都不起作用,解析器认为结束标记是一个实际的结束标记。

这里有一句话值得商榷:

$string = preg_replace('#<br\s*/?>(?:\s*<br\s*/?>)+#i', '<br />', $string);
//                              ^^             ^^

我怎样才能注释掉上面的一行?

7309 次浏览

使用一个技巧: 将两段字符串连接起来。这样,结束标记被切成两半,不再是有效的结束标记。'?>' --> '?'.'>'

在您的代码中:

$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 修饰语-aka 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 解释器的 不受控制,所以它不能工作。

来自 文档: http://php.net/Manual/en/language. basic-syntax.comms.php”rel = “ noReferrer”

“单行”注释样式只能注释到行尾或 当前的 PHP 代码块,以先到者为准。这意味着 HTML 代码后//... ? > 或 # ... ? > 将被打印: ? > 突出 PHP 模式和返回到 HTML 模式,和//或 # 不能影响 那个。

另一个想法是: 转义 >(和 /,如果你想使用 /*...*/注释) :

$string = preg_replace('#<br\s*\/?\>(?:\s*<br\s*\/?\>)+#i', '<br />', $string);

正则表达式引擎忽略“不必要的”转义,但在这种情况下很有用(其他答案中概述了原因)。

为什么要使用复杂的、难以阅读的“技巧”来解决这个问题呢?

为了方便起见,?只是一个量词的快捷方式,所以

只要使用长版的量词 {0,1} ,意思是“最小0最大1出现”:

$string = preg_replace('#<br\s*/{0,1}>(?:\s*<br\s*/{0,1}>)+#i', '<br />', $string);

值得加入 正方体魔术书的其他几种方式:

首先,您可以将 RegEx 压缩为: /(<br\s*/?>)+/i并用 <br />替换(不需要向前查找程序来加重 RegExP 的负担) ,最终您将总是选择 XHMTL 换行符。

修改正则表达式的其他方法,使其不会绊倒 */结束注释或 ?>结束脚本:

  • 使用 所有格限定词: #(<br\s*+/?+>)+#i-这基本上意味着对于 \s*+,如果你发现空格匹配尽可能多,并保持它,对于 /?+,如果你发现一个斜杠保持它!
  • \s*/*包围在捕获组中 = > #(<br(\s*)(/?)>)+#i

现场演示: http://codepad.viper-7.com/YjqUbi

由于我们学习了占有行为,最快的 RegEx 也绕过了评论问题: #(<br\s*+/?+>)++#i 解释演示


至于在棘手的情况下发表评论

如果无法更改代码,或者已经使用了多行注释,则:

1. 使用 Now doc < a href = “ http://php.net/Manual/en/language. typees.string.php”> now doc :

    $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

注意: 现在,博士类似于 Herdoc,但它不解析内容,必须将其 开始分隔符封装在 'single quotes'(注意,< strong > 结尾分隔符不能被标识为 ,必须后跟 ;和 a < strong > 新行 !)中

使用 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