Replace Newlines in String Except Within Certain Tags

By Hawkee on Nov 04, 2012

This will run nl2br on everything inside a string except for what is between the opening and closing tags. For example you can add
's to a comment that contains [ code ] tags without touching the code itself:

$comment = nl2br_excluding($comment, '\', '\[\/code\]');

The opening and closing inputs need to be backslashed and ready for a regular expression to accept them.

The reason I needed to write this was because PHP does not support variable length lookbehind assertions. So this is a solution for anybody who has come across the following error:

Compilation failed: lookbehind assertion is not fixed length

// Replaces newlines on everything except what is in the given tags

function nl2br_excluding($string, $open, $close) {

    $substring = array();

    // Strip the backslashes so we have a clean representation of the tags.
    $open_tag = stripslashes($open);
    $close_tag = stripslashes($close);

    $count = preg_match_all("#$open(.*?)$close#si", $string, $matches);
    for($i = 0; $i < $count; $i++) {

        // Save the substring between the tags in a numbered array.
        $substring[$i] = $matches[1][$i];

        // Replace the substring within the tags with a number so we can replace it later.
        $match = $open_tag.$substring[$i].$close_tag;
        $replace = $open_tag.$i.$close_tag;

        $string = str_replace($match, $replace, $string);

    $string = nl2br($string);

    // After replacing the newlines go back through our substring array and put them back
    // based on their key values.

    foreach($substring as $i => $value) {
        $match = $open_tag.$i.$close_tag;
        $replace = $open_tag.$value.$close_tag;
        $string = str_replace($match, $replace, $string);

    return $string;


Sign in to comment.
Fawkes   -  Nov 09, 2012

@Hawkee Thanks a lot sir. =)

Fawkes   -  Nov 09, 2012

Hawkee, do you know how to replacing triple or more
s to 2
s ?

Hawkee   -  Nov 04, 2012

I found this and wonder if it might be a better solution:

I'm just not sure if XPath can handle bbcode tags.

Are you sure you want to unfollow this person?
Are you sure you want to delete this?
Click "Unsubscribe" to stop receiving notices pertaining to this post.
Click "Subscribe" to resume notices pertaining to this post.