将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