152

One of the lines in my script contains a PHP closing tag inside a string. Under normal operation this does not cause a problem, but I need to comment out the line.

I have tried to comment out this line with //, /* */ and # but none of them work, the parser considers closing tag to be an actual closing tag.

Here is the line in question:

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

What can I do to comment out the above line?

4

6 回答 6

124

使用一个技巧:连接两个部分的字符串。这样,结束标签被一分为二,不再是有效的结束标签。'?>' --> '?'.'>'

在您的代码中:

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

这将使//评论工作。

要使/* */注释起作用,您还必须拆分*/序列:

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

请记住,有时,即使整体大于部分之和——但贪婪是不好的,有时你最好少吃点东西。:)

于 2013-03-05T09:13:07.773 回答
73

最简单的方法

创建一个单独的变量来保存您的正则表达式;这样你就可以简单地注释掉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);
                               ^  ^             ^  ^
于 2013-03-05T09:16:18.923 回答
38

为什么你的尝试没有奏效:

// $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 模式,而 // 或 # 不会影响这一点。

于 2013-03-05T09:31:39.210 回答
15

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

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

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

于 2013-03-05T17:34:15.957 回答
10

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

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

只需使用长版本的量词{0,1},意思是“最少 0 最多 1 次出现”:

$string = preg_replace('#<br\s*/{0,1}>(?:\s*<br\s*/{0,1}>)+#i', '<br />', $string);
于 2013-03-07T06:04:35.667 回答
8

其他一些值得添加到RegEx 技巧书中的方法:

首先,您可以将 RegEx 压缩为:/(<br\s*/?>)+/i并替换为<br />(无需为 RegExP 带来前瞻负担),您将始终以您选择的 XHMTL 换行符结束。

其他修改 RegEx 的方法,使其不会触发*/结束注释或?>结束脚本:

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

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

而且由于我们倾向于所有格行为,因此也绕过评论问题的最快正则表达式是:解释演示#(<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类似,但它不解析内容,并且必须将其起始分隔符用'单引号括起来'请注意,结束分隔符无法识别,必须后跟;一个新行

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

if(false)3. 用or跳过代码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

于 2013-04-10T05:19:18.350 回答