字符串函数
在线手册:中文 英文
PHP手册

nl2br

(PHP 4, PHP 5)

nl2br在字符串所有新行之前插入 HTML 换行标记

说明

string nl2br ( string $string [, bool $is_xhtml = true ] )

在字符串 string 所有新行之前插入 '<br />' 或 '<br>',并返回。

参数

string

输入字符串。

is_xhtml

是否使用 XHTML 兼容换行符。

返回值

返回调整后的字符串。

范例

Example #1 nl2br() 使用范例

<?php
echo nl2br("foo isn't\n bar");
?>

以上例程会输出:

foo isn't<br />
 bar

Example #2 使用 is_xhtml 生成合法的 HTML 标记

<?php
echo nl2br("Welcome\r\nThis is my HTML document"false);
?>

以上例程会输出:

Welcome<br>
This is my HTML document

更新日志

版本 说明
5.3.0 新增可选的 is_xhtml 参数。
4.0.5 nl2br() 成为 XHTML 兼容的操作。所有的旧版本都会在 string 的新行之前插入 '<br>' 而不是 '<br />'。

参见


字符串函数
在线手册:中文 英文
PHP手册
PHP手册 - N: 在字符串所有新行之前插入 HTML 换行标记

用户评论:

rockfalldk at gmail dot com (09-Apr-2012 08:58)

$message = str_replace("\n", "<BR>", $message);

Works just as fine :)

php at djurredeboer dot nl (29-Jul-2011 03:28)

If you use nl2br over a html table you get a lot of new lines above this table. you can fix it by using this function
<?php
$input
= nl2br("
    this is a test<br/>
   
    Aadasd
    asda
    asd
    asd
    <table>
    <td></td>
    <td></td>
    <td></td>   
    </table>"
);
$output = preg_replace_callback('%<table(.*?)>(.*?)</table>%si', 'delTableBr',$input);

function
delTableBr($groups) {
    return
'<table'.$groups[1].'>'.preg_replace('/<br[^>]*?>/si', '',$groups[2]).'</table>';
}

?>
Now it will return
<br />
    this is a test<br/><br />
    <br />
    Aadasd<br />
    asda<br />
    asd<br />
    asd<br />
    <table>
    <td></td>
    <td></td>
    <td></td>
    </table>

matthewkastor at live dot com (18-Apr-2011 04:49)

I was converting text to simple HTML, and converting HTML to plain text. I needed an easy function to convert line breaks, no matter if they were characters or tags, into whatever line break I required at the time. This function worked pretty well. It detects double line breaks and preserves them, as long as the line breaks are in the same format i.e. \r\n \r\n or <br> <br>. It will not preserve a double line break such as <br>\n, instead, it treats this as a single line break for obvious reasons.

The following are recognized as single line breaks, and are replaced using this function:
    \r, \n, \r\n, <BR>, <br>, <br/>, <br />, and any combination of a single tag with any quantity of \r, \n, \r\n following it.

convert_line_breaks.php
<?php
/**
 * Converts newlines and break tags to an
 * arbitrary string selected by the user,
 * defaults to PHP_EOL.
 *
 * In the case where a break tag is followed by
 * any amount of whitespace, including \r and \n,
 * the tag and the whitespace will be converted
 * to a single instance of the line break argument.
 *
 * @author Matthew Kastor
 * @param string $string
 *   string in which newlines and break tags will be replaced
 * @param string $line_break
 *   replacement string for newlines and break tags
 * @return string
 *   Returns the original string with newlines and break tags
 *   converted
 */
function convert_line_breaks($string, $line_break=PHP_EOL) {
   
$patterns = array(   
                       
"/(<br>|<br \/>|<br\/>)\s*/i",
                       
"/(\r\n|\r|\n)/"
   
);
   
$replacements = array(   
                           
PHP_EOL,
                           
$line_break
   
);
   
$string = preg_replace($patterns, $replacements, $string);
    return
$string;
}
?>

mail at fort-hub dot com (18-Feb-2011 11:54)

I noticed that I am using an earlier version of PHP which does not recognise the $xhtml parameter in nl2br(), therefore I am stuck with xhtml line breaks, which I do not want. Thus I made the following simple function:

<?php

   
function NlToBr($inString)
    {
        return
preg_replace("%\n%", "<br>", $inString);
    }

?>

dejan dot marjanovic at gmail dot com (26-Sep-2010 06:53)

Hi, I wrote this function to prevent double lines when doing nl2br with pre tag in HTML. Hope it helps someone.

<?php
function my_nl2br($string){
   
$string = str_replace("\n", "<br />", $string);
    if(
preg_match_all('/\<pre\>(.*?)\<\/pre\>/', $string, $match)){
        foreach(
$match as $a){
            foreach(
$a as $b){
           
$string = str_replace('<pre>'.$b.'</pre>', "<pre>".str_replace("<br />", "", $b)."</pre>", $string);
            }
        }
    }
return
$string;
}
?>

Source: http://webarto.com/59/php-nl2br-pre

Joshua Anderson (12-Jun-2010 05:40)

This function will change new lines (line breaks) to <br/> and it allows you to limit the amount of brs allowed at any point in time.

This function was made to avoid people spaming a textarea with hundreds of line breaks or empty lines.

<?php
function nl2br_limit($string, $num){
   
$dirty = preg_replace('/\r/', '', $string);
$clean = preg_replace('/\n{4,}/', str_repeat('<br/>', $num), preg_replace('/\r/', '', $dirty));
   
return
nl2br($clean);
}

echo
nl2br_limit($string,'4');
?>

// Heres how it works //

nl2br_limit($string, $num)
// $string is the entered text you want to strip lines out of, it could be ($_POST['myinput'])
// $num is the amount of consecutive <br/>'s that are allowed any at a time.

The user is allowed to enter as many line breaks as $num allows

Jose Canciani (19-May-2010 04:57)

Recursive solution to avoid replacing newlines inside <pre> tags:

<?php
   
function findOpenPre($line) {
       
$start = strpos($line,'<pre');
        if (
$start === false) {
            return
nl2br($line);
        } else {
            return
nl2br(substr($line,0,$start-1)).findClosePre(substr($line,$start));
        }
    }
   
    function
findClosePre($line) {
       
$start = strpos($line,'</pre>');
        if (
$start === false) {
            return
$line.'</pre>'; # should never come here
       
} else {
            return
substr($line,0,$start+6).findOpenPre(substr($line,$start+7));
        }
    }

    echo
findOpenPre('hello '.chr(10).'<pre> world'.chr(10).'</pre>');
?>

will return "hello <br><pre> world\n</pre>"
instead of "hello <br><pre> world<br></pre>"

Jose.

gx (03-May-2010 05:02)

*Strictly* reverts PHP's nl2br() effects (whether it was used in XHTML mode or not):

<?php
function nl2br_revert($string) {
    return
preg_replace('`<br(?: /)?>([\\n\\r])`', '$1', $string);
}
?>

Indeed, in a string which was just nl2br'd:
- a BR added by PHP is directly followed by a \n or a \r character, and vice versa
- a PHP-added BR is either "<br />" or "<br>" (no need to match "<br/>", "<br   />", "<BR>"...)
Thus this function only removes PHP-added BRs (which "strictly reverts" meant).

The following would be even more logical, as nl2br() doesn't use both BR forms at once:
<?php
function nl2br_revert_bis($string) {
   
$br = preg_match('`<br>[\\n\\r]`',$string) ? '<br>' : '<br />';
    return
preg_replace('`'.$br.'([\\n\\r])`', '$1', $string);
}
?>

If you don't want to use regular expressions, here are "plain" alternatives:
<?php
function nl2br_revert_noregex($string) {
   
// watch for order in arrays
    // (the first 2 elements are for the case nl2br() was used in old HTML mode)
   
return str_replace(
        array(
"<br>\n",   "<br>\r",   "<br />\n", "<br />\r"),
        array(
"<br />\n", "<br />\r",       "\n",       "\r"),
       
$string
   
);
}

function
nl2br_revert_bis_noregex($string) {
   
$br = (strpos($string,"<br>\n")!==false || strpos($string,"<br>\r")!==false) ? '<br>' : '<br />';
    return
str_replace(
        array(
$br."\n", $br."\r"),
        array(   
"\n",     "\r"),
       
$string
   
);
}
?>

james bandit.co dot nz (30-Apr-2010 07:13)

convert multiple new lines to p tags with an optional class assigned to the p tags

<?php
   
function nl2p($string, $class='') {
       
$class_attr = ($class!='') ? ' class="'.$class.'"' : '';
        return
           
'<p'.$class_attr.'>'
           
.preg_replace('#(<br\s*?/?>\s*?){2,}#', '</p>'."\n".'<p'.$class_attr.'>', nl2br($string, true))
            .
'</p>';
    }
?>

SebastianJu (30-Nov-2009 09:49)

Another br2nl-Function. This works with text for textareas too... Other solutions here would result in \n in the textbox and no wrap.

<?php
function br2nl($string){
 
$return=eregi_replace('<br[[:space:]]*/?'.
   
'[[:space:]]*>',chr(13).chr(10),$string);
  return
$return;
}
?>

Grü?e!
Sebastian

leaf at leafo dot net (26-Jun-2009 09:02)

for the <pre> tag problem, the reason why nl2br does that is because it converts all \n to <br />\n
(see the extra \n there)

an easy hack is to use strtr to replace all \n with just <br />

eg.
<?php
function mynl2br($text) {
   return
strtr($text, array("\r\n" => '<br />', "\r" => '<br />', "\n" => '<br />'));
}
?>

very simple and very fast. the only disadvantage is that anyone reading your nl2br'd html will see it all on one line.

eric dot NOSPAM dot dillenseger at gmail dot com (10-Apr-2009 10:34)

An addition to sean' function:
Please read http://www.php.net/manual/en/function.strpos.php and the warning about return values of strpos().

<?php
// (... snip ...)
   
if(!strpos($string, "<pre>"))  // triggered if <pre> is at the beginning of the string
// (... snip ...)
       
if(strpos($line, "<pre>")) // this time, not triggered if <pre> is at the beginning of the line
// (... snip ...)
?>

Avoid shortcuts and compare boolean results strictly with '==='.

BTW, <pre> elements aren't allowed inside <p> elements (xhtml strict) so one would avoid putting a <br /> element at the end of a <pre> element.

<?php
// do nl2br except when in a pre tag
function nl2brPre($string)
{
   
// First, check for <pre> tag
   
if(strpos($string, "<pre>") === false)
    {
        return
nl2br($string);
    }

   
// If there is a <pre>, we have to split by line
    // and manually replace the linebreaks with <br />
   
$strArr=explode("\n", $string);
   
$output="";
   
$preFound=3;

   
// Loop over each line
   
foreach($strArr as $line)
    {   
// See if the line has a <pre>. If it does, set $preFound to true
       
if(strpos($line, "<pre>") === true)
        {
           
$preFound=1;
        }
        elseif(
strpos($line, "</pre>"))
        {
           
$preFound=2;
        }

       
// If we are in a pre tag, just give a \n, else a <br />
       
switch($preFound) {
            case
1: // found a <pre> tag, close the <p> element
               
$output .= "</p>\n" . $line . "\n";
                break;
            case
2: // found the closing </pre> tag, append a newline and open a new <p> element
               
$output .= $line . "\n<p>";
               
$preFound = 3; // switch to normal behaviour
               
break;
            case
3: // simply append a <br /> element
               
$output .= $line . "<br />";
                break;
        }
    }

    return
$output;
}
?>

sean at boyercentral dot net (03-Mar-2009 03:22)

Ever had a problem with using nl2br() for something like a blog post which contains anything inside of a <pre> tag? It will give you double spaces. Ugly for posting code examples. Here's my solution.

If it doesn't detect a <pre> tag inside of the $string you pass in, it uses regular ol' nl2br(). Otherwise, it explodes the string by \n, and only adds <br /> to lines that are NOT inside the <pre> tag!

This function completely avoids using RegEx and stacks. Simple, and fairly fast.

<?php
// do nl2br except when in a pre tag
function nl2brPre($string)
{
   
// First, check for <pre> tag
   
if(!strpos($string, "<pre>"))
    {
        return
nl2br($string);
    }

   
// If there is a <pre>, we have to split by line
    // and manually replace the linebreaks with <br />
   
$strArr=explode("\n", $string);
   
$output="";
   
$preFound=false;

   
// Loop over each line
   
foreach($strArr as $line)
    {   
// See if the line has a <pre>. If it does, set $preFound to true
       
if(strpos($line, "<pre>"))
        {
           
$preFound=true;
        }
        elseif(
strpos($line, "</pre>"))
        {
           
$preFound=false;
        }
       
       
// If we are in a pre tag, just give a \n, else a <br />
       
if($preFound)
        {
           
$output .= $line . "\n";
        }
        else
        {
           
$output .= $line . "<br />";
        }
    }

    return
$output;
}
?>

Hope this comes in handy!

N/A (29-Oct-2008 03:41)

Here's a more simple one:

<?php
/**
 * Convert BR tags to nl
 *
 * @param string The string to convert
 * @return string The converted string
 */
function br2nl($string)
{
    return
preg_replace('/\<br(\s*)?\/?\>/i', "\n", $string);
}
?>

Enjoy

rphsm at hotmail dot com (30-Apr-2008 09:56)

function to replace all \n\n\n\n\n\n \r\r\r\r only one <br />

<?php
function Only1br($string)
{
    return
preg_replace("/(\r\n)+|(\n|\r)+/", "<br />", $string);
}

$string = "this is \n\n\n a String with many \n\n\r\r returns!";

$string = Only1br($string);

//returns: this is <br /> a String with many <br /> returns!";
?>

blacknine313 at gmail dot com (02-Apr-2008 02:34)

After a recent post at the forums on Dev Shed, I noticed that it isn't mentioned, so I will mention it.

nl2br returns pure HTML, so it should be after PHP anti-HTML functions ( such as strip_tags and htmlspecialchars ).

nacho dot exr at gmail dot com (31-Oct-2007 04:56)

Simple function that converts more than one <br>,<br/>,<br />... to a <p></p>. Maybe it's useful for someone =)

<?php
function br2p($string)
{
  return
preg_replace('#<p>[\n\r\s]*?</p>#m', '', '<p>'.preg_replace('#(<br\s*?/?>){2,}#m', '</p><p>', $string).'</p>');
}
?>

Useful used with nl2br:
<?php
br2p
(nl2br(...));
?>

hyponiq at gmail dot com (26-Aug-2007 07:03)

On the contrary, <b>mark at dreamjunky.comno-spam</b>, this function is rightfully named.  Allow me to explain.  Although it does re-add the line break, it does so in an attempt to stay standards-compliant with the W3C recommendations for code format.

According to said recommendations, a new line character must follow a line break tag.  In this situation, the new line is not removed, but a break tag is added for proper browser display where a paragraph isn't necessary or wanted.

moester at g-mail (25-Feb-2007 09:45)

<?php
function nls2p($str)
{
  return
str_replace('<p></p>', '', '<p>'
       
. preg_replace('#([\r\n]\s*?[\r\n]){2,}#', '</p>$0<p>', $str)
        .
'</p>');
}
?>

Turns two or more consecutive newlines (separated by possible white space) into a <p>...</p>.

Pass result to regular nl2br() to add <br/> to remaining nl's, eg,

<?php
echo nl2br(nls2p("Paragraph1\n\nParagraph2\n line1\n line2\n"));
?>

result:

<p>Paragraph1</p>
<p>Paragraph2<br/>
line1<br/>
line2<br/></p>

ngkongs at gmail dot com (23-Feb-2007 12:12)

to replace all linebreaks to <br />
the best solution (IMO) is:

<?php
function nl2br2($string) {
$string = str_replace(array("\r\n", "\r", "\n"), "<br />", $string);
return
$string;
}
?>

because each OS have different ASCII chars for linebreak:
windows = \r\n
unix = \n
mac = \r

works perfect for me

fili at fili dot nl (11-Feb-2007 07:07)

<?php
function p2nl ($str) {
    return
preg_replace(array("/<p[^>]*>/iU","/<\/p[^>]*>/iU"),
                        array(
"","\n"),
                       
$str);
}

$string = "0<p>1</p><p>2</p>3";
var_dump(p2nl($string));

/*
Output:
   
    string(6) "01
    2
    3"
*/
?>

Moore (at) Hs-Furtwangen (dot) De (18-Aug-2006 07:13)

Here a litle function that might come handy one time:
It gives back a String and adds a <BR> (you can change it to <br />) to every line end. And it adds $num blanks to the front of the next line.

<?php
 
function nl2brnl($text, $num)
  {
   return
preg_replace("/\\r\\n|\\n|\\r/", sprintf("% -".(5+$num)."s","<BR>\\n"), $text);
  }

$a = " one\\n two\\r\\n three";

$b = nl2brnl($a, 2);

var_dump($b);

/* output will be:
string(30) " one<BR>
   two<BR>
   three"
*/

echo "  <P>\\n  ";
echo
$b

/* output will be:
  <P>
   one<BR>
   two<BR>
   three
*/
?>

Is helpfull for avouding code_soup.

godfrank DOMAIN-IS msn TLD-IS com (18-May-2006 05:12)

I have modified my function found in the previous post.

It now uses preg_replace() which should technically be faster than ereg_replace(). You can also specify what you want to replace "\r\n" with. If you use the function with only one parameter, it will use '<br />' by default.

<?php
function nl2brStrict($text, $replacement = '<br />')
{
    return
preg_replace("((\r\n)+)", trim($replacement), $text);
}
?>

chayden at chayden dot com (10-Mar-2006 11:07)

Using buzoganylaszlo at yahoo dot com simple nl2p function, I've written a more HTML compliant function to deal with line breaks ...

<?php

/* FORMATS LINE BREAKS WITH PROPER HTML TAGS */
function format_html($content)
 {
 
$content = "<p>" . str_replace("\r\n", "<br/>", $content) . "";
 
$content = "" . str_replace("<br/><br/>", "</p><p>", $content) . "";
  return
"" . str_replace("<br/><li>", "<li>", $content) . "";
 }

?>

Here is an example of its use ...

<?php

/* CONTENT TO BE PROCCESSED */
$content = "This is a\r\nline break.\r\n\r\nAnd this is a new paragraph.";

/* USE OF format_html FUNCTION */
/* NOTE: If you want 100% proper HTML tags, you'll need to add a closing paragraph tag (</p>) as shown below. */
echo format_html("$content</p>");

?>

The above will print ...

<p>This is a
<br/>line break.

<p>And this is a paragraph.</p>

Anders Norrbring (09-Mar-2006 09:49)

Seems like I was a bit too quick and left out the vital part, and I also missed to escape the slashes in the post...

<?php
function br2nl($text)
{
    return 
preg_replace('/<br\\\\s*?\\/??>/i', "\\n", $text);
}
?>

Anders Norrbring (09-Mar-2006 09:28)

Seeing all these suggestions on a br2nl function, I can also see that neither would work with a sloppy written html line break.. Users can't be trusted to write good code, we know that, and mixing case isn't too uncommon.

I think this little snippet would do most tricks, both XHTML style and HTML, even mixed case like <Br> <bR /> and even <br            > or <br     />.

<?php
function br2nl($text)
{
    return 
preg_replace('/<br\\s*?\/??>/i', '', $text);
}
?>

tom dot crawford at emailsystems dot com (11-Jan-2006 10:32)

Note to foltscane at yahoo dot com

Wouldn't it be easier to do this:

$encoded_string = nl2br( htmlentities( $string_to_encode ) );

buzoganylaszlo at yahoo dot com (05-Jan-2006 12:51)

There is a simple nl2p function:

<?php
function nl2p($text) {
  return
"<p>" . str_replace("\n", "</p><p>", $text) . "</p>";
}
?>

foltscane at yahoo dot com (03-Jan-2006 04:47)

I was interested in changing \n to <BR> but then still having htmlentities enforced inbetween these added <BR>s. So I wrote this simple textentities which will do just that.

function textentities($s)
{
    while($sp = strpos($s,"\n"))
    {
        echo htmlentities(substr($s,0,$sp))."<BR>";
        $s = substr($s,$sp+1,strlen($s));       
    }
    echo htmlentities($s);
}

btm at anfo dot pl (20-Dec-2005 11:22)

Comment on emailfire at gmail dot com nl2brr. It should be:
<? return str_replace(array("\r\n", "\n", "\r"), "<br>", $text); ?>
You've forgotten the backslashes.

jonasnicklas at hotmail dot com (19-Dec-2005 10:04)

Re: emailfire

The function emailfire posted is missing some backslashes, a better alternative to it is:

<?php

$foo
= "This\nis a\r\ntest\rmessage";

function
nl2brr($text)
{
    return
preg_replace("/\r\n|\n|\r/", "<br>", $text);
}

echo
nl2brr($foo);

# Output: This<br>is a<br>test<br>message

?>

I put both functions in a for-loop and surprisingly preg_replace is a lot faster, I assume this is because str_replace will search the string several times. If you know what kind of breaks (Windows/Unix) you are expecting it is obviously better to use str_replace.

A note: Internet Explorer does not have any XHTML support, even browsers that DO have XHTML support (such as Firefox or Opera) will not parse pages as XHTML unless told so via a Header (for example through php's header function, like <?php header(Content-type: application/xhtml+xml); ?>), the tag <br /> is invalid in HTML 4. Since all browsers show it correctly anyway (though according to the specification they shouldn't), you could simply not care...

silya at rfvnu dot lg dot ua (04-Dec-2005 04:02)

Trouble was with file function when long tags where broken by \r\n and function strip_tags worked not correctly with every element of array. This step prepare string from file for using function file and then strip_tags. (For example, html file generated by M$ Word)

<?php
$str
= file_get_contents($filename);
$str = str_replace("\r\n", "\n", $str);
$opentag = 0;
$nl = 0;
for(
$i = 0; $i < strlen($str); $i++)
{
   if(
$opentag == 1 && $str[$i] == "\n")
   {
     
$str[$i] = '  ';
      continue;
   }

   if(
$str[$i] == '<')
     
$opentag = 1;
   elseif(
$str[$i] == '>')
     
$opentag = 0;
   else ;

}
?>

thunberg at gmail dot com (14-Sep-2005 07:15)

I wrote this because I wanted users to be able to do basic layout formatting by hitting enter in a textbox but still wanted to allow HTML elements (tables, lists, etc). The problem was in order for the output to be correct with nl2br the HTML had to be "scrunched" up so newlines wouldn't be converted; the following function solved my problem so I figured I'd share.

<?php

function nl2br_skip_html($string)
{
   
// remove any carriage returns (mysql)
   
$string = str_replace("\r", '', $string);

   
// replace any newlines that aren't preceded by a > with a <br />
   
$string = preg_replace('/(?<!>)\n/', "<br />\n", $string);

    return
$string;
}

?>

webmaster at cafe-clope dot net (13-Aug-2005 11:50)

based on previous notes, a generalist function that works with any <tag>...</tag>, and its ^-1. (use it with "li", for example) :

<?php
function nl2any($string, $tag = 'p', $feed = '') {
 
// making tags
 
$start_tag = "<$tag" . ($feed ? ' '.$feed : '') . '>' ;
 
$end_tag = "</$tag>" ;
 
 
// exploding string to lines
 
$lines = preg_split('`[\n\r]+`', trim($string)) ;
 
 
// making new string
 
$string = '' ;
  foreach(
$lines as $line)
   
$string .= "$start_tag$line$end_tag\n" ;
 
  return
$string ;
}
   
function
any2nl($string, $tag = 'p') {
 
//exploding
 
preg_match_all("`<".$tag."[^>]*>(.*)</".$tag.">`Ui", $string, $results) ;
 
// reimploding without tags
 
return implode("\n", array_filter($results[1])) ;
}
?>

I just had a problem when trying "`<$tag[^>]*>(.*)</$tag>`Ui" regexp string, I can't figure out why.

x against capital x at x everywhere x (12-Aug-2005 01:47)

Regarding last post by admin at ninthcircuit, I think:

"rather than get into nasty regular expressions" === "I don't understand regular expressions"

No offense, but please be aware that kristen's solution is much more robust.  The ninthcircuit solution will miss cases when there are differences in case (e.g., BR instead of br) and when there is more than one space between the r and the / (e.g., <br    />).

We all like robust code, don't we?

admin at ninthcircuit dot info (06-Jun-2005 10:00)

As stated in the manual above, PHP's nl2br() feature only puts a "<br />" tag before each newline ("\n"). So -- if you intend to code a br2nl() function for yourselves, all you have to do is remove every occurence of "<br />" or "<br>".

Rather than get into nasty regular expressions to accomplish this, just use what PHP has built in already --  str_replace():

<?php
   
/* br2nl for use with HTML forms, etc. */
   
function br2nl($text)
    {
       
/* Remove XHTML linebreak tags. */
       
$text = str_replace("<br />","",$text);
       
/* Remove HTML 4.01 linebreak tags. */
       
$text = str_replace("<br>","",$text);
       
/* Return the result. */
       
return $text;
    }
?>

The final result from this function being called is whatever was entered before XHTML/HTML linebreaks were added.

All newlines are preserved by default, as per PHP ln2br() specification. Since the code above preserves newlines also, you can expect your data to reappear in the same way it was entered.

Hope this helps.

kristen at paristemi dot com (16-May-2005 09:12)

A note to add to the br2nl. Since nl2br doesn't remove the line breaks when adding in the <br /> tags, it is necessary to strip those off before you convert all of the tags, otherwise you will get double spacing. Here is the modified function:

function br2nl($str) {
    $str = preg_replace("/(\r\n|\n|\r)/", "", $str);
    return preg_replace("=<br */?>=i", "\n", $str);
}

sebastian at no spam flashhilfe.de (10-May-2005 04:16)

// Convert only <br> <br /> and <br     /> to newline

function br2nl($str) {
   return preg_replace('=<br */?>=i', "\n", $str);
}

The Script at the bottom whit '!<br.*>!iU' match tags like <break> or something.

jochem at vuilnisbak dot com (02-Apr-2005 04:43)

For people trying br2nl, but getting stuck at double newlines (or at least more then needed), try this:

<?php
function br2nl($coffee) {
   
$coffee = str_replace("\r\n", "\n", $coffee); // make from windows-returns, *nix-returns
   
$coffee = str_replace("<br />\n", "\n", $coffee); // to retrieve it
   
return $coffee;
}
?>

The first thing \r\n is replacing linebreaks made on Windows systems. I believe *nix systems only place \n (not sure about it).

Have fun.

Jochem

webKami [at] akdomains.com (01-Apr-2005 12:54)

here is the CSS friendly version, called nl2li_css()

Inputs a param css_class (default ="none") and pass it as class of All <li> List Items.

<?
function nl2li_css($str,$css_class = "none",$ordered = 0, $type = "1") {

//check if its ordered or unordered list, set tag accordingly
if ($ordered)
{
    $tag="ol";
    //specify the type
    $tag_type="type=$type";
}
else
{   
    $tag="ul";
    //set $type as NULL
    $tag_type=NULL;
}

// add ul / ol tag
// add tag type
// add first list item starting tag - use css class
// add last list item ending tag
$str = "<$tag $tag_type><li class=\"$css_class\">" . $str ."</li></$tag>";

//replace /n with adding two tags
// add previous list item ending tag
// add next list item starting tag - use css class
$str = str_replace("\n","</li><br />\n<li class=\"$css_class\">",$str);

//spit back the modified string
return $str;
}
?>

Suggestions welcome again :)

webkami [at] gmail dout com (30-Mar-2005 03:42)

A handy function to convert new line \n seprated text into ordered or unordered list. I am calling it nl2li, suggestions welcome. Second optional parameter sets the list as ordered (1) or unordered (0 = default). Third parameter can be used to specify type of ordered list, valid inputs are "1" = default ,"a","A","i","I".

function nl2li($str,$ordered = 0, $type = "1") {

//check if its ordered or unordered list, set tag accordingly
if ($ordered)
{
    $tag="ol";
    //specify the type
    $tag_type="type=$type";
}
else
{   
    $tag="ul";
    //set $type as NULL
    $tag_type=NULL;
}

// add ul / ol tag
// add tag type
// add first list item starting tag
// add last list item ending tag
$str = "<$tag $tag_type><li>" . $str ."</li></$tag>";

//replace /n with adding two tags
// add previous list item ending tag
// add next list item starting tag
$str = str_replace("\n","</li><br />\n<li>",$str);

//spit back the modified string
return $str;
}

mike at openconcept dot ca (10-Mar-2005 06:02)

There are other nl2p examples above, but think this one will provide nicer html.  Also threw in a very related br2p function for all of those folks who want to strip away the <br /> tags which give their designers the blues.

   /**
    * replacement for php's nl2br tag that produces more designer friendly html
    *
    * Modified from: http://www.php-editors.com/contest/1/51-read.html
    *
    * @param string $text
    * @param string $cssClass
    * @return string
    */
    function nl2p($text, $cssClass=''){

      // Return if there are no line breaks.
      if (!strstr($text, "\n")) {
         return $text;
      }

      // Add Optional css class
      if (!empty($cssClass)) {
         $cssClass = ' class="' . $cssClass . '" ';
      }

      // put all text into <p> tags
      $text = '<p' . $cssClass . '>' . $text . '</p>';

      // replace all newline characters with paragraph
      // ending and starting tags
      $text = str_replace("\n", "</p>\n<p" . $cssClass . '>', $text);

      // remove empty paragraph tags & any cariage return characters
      $text = str_replace(array('<p' . $cssClass . '></p>', '<p></p>', "\r"), '', $text);

      return $text;

   } // end nl2p

  /**
    * expanding on the nl2p tag above to convert user contributed
    * <br />'s to <p>'s so it displays more nicely.
    *
    * @param string $text
    * @param string $cssClass
    * @return string
    */
    function br2p($text, $cssClass=''){

      if (!eregi('<br', $text)) {
         return $text;
      }

      if (!empty($cssClass)) {
         $cssClass = ' class="' . $cssClass . '" ';
      }

      // put all text into <p> tags
      $text = '<p' . $cssClass . '>' . $text . '</p>';

      // replace all break tags with paragraph
      // ending and starting tags
      $text = str_replace(array('<br>', '<br />', '<BR>', '<BR />'), "</p>\n<p" . $cssClass . '>', $text);

      // remove empty paragraph tags
      $text = str_replace(array('<p' . $cssClass . '></p>', '<p></p>', "<p>\n</p>"), '', $text);

      return $text;
}

This is all code from Back-End CMS (http://www.back-end.org), a template based gpl php/mysql cms.

Mike

freedman AT freeformit . com (04-Mar-2005 12:45)

here's a modified version that allows the addition of style tags to the <p> marker

function nl2p($str,$addtag='') {
    return str_replace('<p'.$addtag.'></p>', '', '<p'.$addtag.'>' . preg_replace('#\n|\r#', '</p>$0<p'.$addtag.'>', $str) . '</p>');
}

$x = "abc\ndef"
echo nl2p($x);  // outputs <p>abc</p>\n<p>def</p>

echo nl2p($x,' style="text-align:justify"');
// outputs <p style="text-align:justify">abc</p>\n<p style="text-align:justify">def</p>

asentis at gmail dot com (24-Feb-2005 01:06)

If you want to respect W3C, you can use this function :

<?php
function nl2p($str)
{
  return
str_replace('<p></p>', '', '<p>' . preg_replace('#\n|\r#', '</p>$0<p>', $str) . '</p>');
}
?>

Cya :)

CGameProgrammer at gmail dot com (31-Jan-2005 01:28)

It's important to remember that this function does NOT replace newlines with <br> tags. Rather, it inserts a <br> tag before each newline, but it still preserves the newlines themselves! This caused problems for me regarding a function I was writing -- I forgot the newlines were still being preserved.

If you don't want newlines, do:

<?php
$Result
= str_replace( "\n", '<br />', $Text );
?>

(17-Jan-2005 08:04)

string nl2br_indent ( string string [, mixed indent] )

This function adds break tags before newlines as nl2br and also indents the text.
If indent is not specified, string will not be indented.

<?php

function nl2br_indent($string, $indent = 0)
{
   
//remove carriage returns
   
$string = str_replace("\r", '', $string);

   
//convert indent to whitespaces if it is a integer.
   
if (is_int($indent)) {
       
//set indent to length of the string
       
$indent = str_repeat(' ', (int)$indent);
    }

   
//replace newlines with "<br />\n$indent"
   
$string = str_replace("\n", "<br />\n".$indent, $string);
   
//add  the indent to the first line too
   
$string = $indent.$string;

    return
$string;
}

?>

This is for example useful to indent text in html tags:

<?php

$str
= 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
In massa nunc, cursus eu, tincidunt in, eleifend non, enim. In ut felis. Nunc
scelerisque ante vel risus. Nulla quis metus non elit scelerisque tincidunt.'

echo '<html>'."\n";
echo
'  <p>'."\n";
echo
nl2br_indent($str, 4)."\n";
echo
'  </p>'."\n";
echo
'</html>'."\n";

?>

will return:

<html>
  <p>
    Lorem ipsum dolor sit amet, consectetuer adipiscing elit.<br />
    In massa nunc, cursus eu, tincidunt in, eleifend non, enim. In ut felis. Nunc<br />
    scelerisque ante vel risus. Nulla quis metus non elit scelerisque tincidunt.
  </p>
</html>

- $str is indented by 4 spaces.

spertica at tiscalinet dot it (14-Jan-2005 09:23)

An easy way to get HTML formatted with <br> from a ASCII text file with CR & LF:

<?php
      $string_text
=file_get_contents("/path_to/file.txt"); // load text file in var
     
$new_text=nl2br($string_text); // convert CR & LF in <br> in newvar
     
echo $new_text; // print out HTML formatted text
     
unset($string_text, $new_text); // clear all vars to unload memory
 
?>

php at keithtyler dot com (05-Nov-2004 06:58)

Take extreme care with nl2br(). It is a simple replacement function -- apparently equivalent to preg_replace("\n","<br \>\n").

It should not be used on input from HTML textareas, unless all HTML tags are stripped from the input first. nl2br() does not do anything special to newlines that occur within HTML elements (such as the <a> anchor tag).

Some browsers will submit textarea data with newlines inserted at the points where the user's input wrapped to the next line. This can cause anchor links to break and other erratic appearance of HTML:

<a <br \>href=http://us2.php.net/manual/en/function.nl2br.php>PHP nl2br()</a>

or worse:

<a href="http://www.site.com/user/page with <br />spaces.html">URL with spaces</a>

A lot of people use nl2br() to allow their users to insert explicit line and paragraph breaks via newlines, and their applications will exhibit this problem when used with such browsers.

php at sharpdreams dot com (06-Apr-2004 05:52)

Better br2nl function (allows for non-valid XHTML tags). I find it useful for parsing 3rd party websites to convert their screwy BR formats to \n.

<?php
function br2nl( $data ) {
    return
preg_replace( '!<br.*>!iU', "\n", $data );
}
?>

greywyvern - greywyvern - com (05-Feb-2004 09:11)

Just a couple adjustments to the function below.

<?php

function nl2br_pre($string, $wrap = 40) {
 
$string = nl2br($string);

 
preg_match_all("/<pre[^>]*?>(.|\n)*?<\/pre>/", $string, $pre1);

  for (
$x = 0; $x < count($pre1[0]); $x++) {
   
$pre2[$x] = preg_replace("/\s*<br[^>]*?>\s*/", "", $pre1[0][$x]);
   
$pre2[$x] = preg_replace("/([^\n]{".$wrap."})(?!<\/pre>)(?!\n)/", "$1\n", $pre2[$x]);
   
$pre1[0][$x] = "/".preg_quote($pre1[0][$x], "/")."/";
  }

  return
preg_replace($pre1[0], $pre2, $string);
}

?>

You might ask, why not just use:
<?php $string = str_replace("\n", "<br />", $string); ?>

... and prevent double spacing that way by actually *replacing* the \n with <br />, whereas nl2br() *inserts* a <br />.

Well, the answer is, doing it that way makes all the HTML output appear on a single line!  Ugly, to say the least.  The function above will keep your HTML source output formatted the same way you input it. :)

matt at mullenweg dot com (16-Oct-2002 04:23)

I put together a little function to convert multiple line breaks into XHTML paragraph tags. It also changes newlines within the psuedo-paragraphs to <br />. This should be well suited to CMS where (in my case) you don't want the client to deal with *any* HTML but you still want proper paragraphs for your pages.

USAGE: You can write your text just like I have here, using the enter key as the only formatting tool. This can probably be made more efficient and I'll keep an updated (and unmangled) version of it at
http://www.photomatt.net/scripts/autop