Convert PHP closing tag into comment

Use a trick: concatenate the string from two pieces. This way, the closing tag is cut in two, and is not a valid closing tag anymore. '?>' --> '?'.'>'

In your code:

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

This will make // comments work.

For /* */ comments to work, you'd have to split the */ sequence too:

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

Remember, sometimes, even though the whole is more than the sum of its parts - but being greedy is bad, there are times you are better left with less. :)


The easiest way

Create a separate variable to hold your regular expression; this way you can simply comment out the preg_replace() statement:

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

Fix using character classes

To fix line comments, you can break up ?> by putting > inside a character class like so:

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

To fix block comments, you can apply it to /:

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

To fix both comment styles, you can put / and > in their own character class.

Fix using the /x modifier

The x modifier - aka PCRE_EXTENDED - ignores spaces and newlines in a regular expression (except when they occur inside a character class); this makes it possible to add spaces to separate the problematic characters. To fix both comment styles:

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

Why your attempts didn't work:

// $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

What works:

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

Further...

After the above, you should be able to use /* to comment out the line. If you leave the ?> intact, // cannot possibly comment out an entire line. The text following ?> could be html, which is outside the control of the PHP interpreter, so that wouldn't work.

From the documentation:

The "one-line" comment styles only comment to the end of the line or the current block of PHP code, whichever comes first. This means that HTML code after // ... ?> or # ... ?> WILL be printed: ?> breaks out of PHP mode and returns to HTML mode, and // or # cannot influence that.


Another idea: Escape the > (and the /, if you want to use a /*...*/ comment):

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

An "unnecessary" escape is ignored by the regex engine, but is useful in this case (for reasons outlined in the other answers).