2020年3月

php有一个函数nl2br,可以把文本中的换行符变成 《br /》,但是有的时候,我们需要的是单个换行符换行变成《br /》,两个及以上换行符变成《p》。(注:这里的中文书名号其实要写成英文尖括号的,原因你懂得。)
网上搜索nl2p第一个就是cnblogs这个博客,那我姑且当做他是源站点吧。
https://www.cnblogs.com/hejianrong/p/5802010.html
源码摘抄如下

/**
 * Returns string with newline formatting converted into HTML paragraphs.
 *
 * @param string $string String to be formatted.
 * @param boolean $line_breaks When true, single-line line-breaks will be converted to HTML break tags.
 * @param boolean $xml When true, an XML self-closing tag will be applied to break tags (<br />).
 * @return string
 */
function nl2p($string, $line_breaks = true, $xml = true)
{
    // Remove existing HTML formatting to avoid double-wrapping things
    $string = str_replace(array('<p>', '</p>', '<br>', '<br />'), '',$string);
     
    // It is conceivable that people might still want single line-breaks
    // without breaking into a new paragraph.
    if ($line_breaks == true)
        return '<p>'.preg_replace(array("/([\n]{2,})/i","/([^>])\n([^<])/i"), array("</p>\n<p>", '<br'.($xml == true ? ' /' :'').'>'), trim($string)).'</p>';
    else
        return '<p>'.preg_replace("/([\n]{1,})/i", "</p>\n<p>", trim($string)).'</p>';
}

这个函数有两个选项。当然我觉得$xml要恒等于true的,因为现在html5提倡闭合的写法,就是< br / >这样。
然后$line_breaks=false 是换行即换段落,ture是换行就是换行,但是英文会删去前一行最后一个字和第二行第一个字,中文会变成乱码(因为中文通常是2-3字符)。

我想要的功能是一个换行符就是换行,两个或以上就是段落。
但我对正则又不熟悉。最后折腾后终于改造成自己的nl2p。如下

function nl2p($string)
{
    // Remove existing HTML formatting to avoid double-wrapping things
    $string = str_replace(array('<p>', '</p>', '<br>', '<br />'), '',$string);

    // It is conceivable that people might still want single line-breaks
    // without breaking into a new paragraph.
    
      return '<p>'.preg_replace(array("/([\n]{2,})/i","/[\n]/i"), array("</p><p>", '<br />'), trim($string)).'</p>';
}

经过测试,非常完美。