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;
}
I found this and wonder if it might be a better solution:
http://stackoverflow.com/questions/8916119/php-replace-n-except-where-other-valid-html-tags-appear
I'm just not sure if XPath can handle bbcode tags.