将HTML段落转换为换行符

时间:2013-03-14 21:12:06

标签: php content-management-system preg-replace newline preg-match-all

我正在为我的博客改进我的基本CMS。今天我添加了一个新函数,它将数据库中的(双)换行符转换为段落标记。

function nl2p($str) {
    $pattern = '/\n\n/';
    $replacement = '</p><p>';
    return preg_replace($pattern, $replacement, $str);
}

这项工作正常,但我不想在<p>代码中添加任何<pre>代码。所以我想我会扩展我的功能,将所有<p>标签重新转换为换行符,但它不起作用。关于为什么的任何想法?

function nl2p($str) {
    $pattern = '/\n\n/';
    $replacement = '</p><p>';
    $par = preg_replace($pattern, $replacement, $str);

    preg_match_all('/\<pre\>(.*?)\<\/pre\>/', $par, $pre_content);
    return preg_replace($replacement, $pattern, $pre_content[0]);
}

编辑:由于这似乎是一个难以破解的问题,或许我应该为我的代码添加一些上下文。我正在使用syntax highlighter在我的博客上以原始格式显示代码。荧光笔是用Javascript编写的,并利用HTML中预先格式化的标签来显示代码。

另外,我上面的nl2p函数是我的博客类的一种方法。问题是它使用我预先格式化的标签以原始格式(即可见)放置预先格式化的标签。

编辑2:以下是一些示例代码。首先是数据库中的原始代码,然后是格式化的HTML代码。另一个奇怪的细节是,下面代码中的最后一个</p>在源代码中实际上不可见。它发布在关闭预标签之后。

<pre name="code" class="brush: javascript">
var data = [10, 20, 30];

var svg = d3.select("body")
.append("svg")
.attr("width", 500)
.attr("height", 500);

var circle = svg.selectAll("circle")
          .data(data)
          .enter()
            .append("circle")
            .attr("cx", function (d) { return d * 10; })
            .attr("cy", 50)
            .attr("r", function (d) { return d; })
            .style("fill", "red");</pre>

----------

var data = [10, 20, 30];<p></p><p>var svg = d3.select("body")
.append("svg")
.attr("width", 500)
.attr("height", 500);

var circle = svg.selectAll("circle")
          .data(data)
          .enter()
            .append("circle")
            .attr("cx", function (d) { return d * 10; })
            .attr("cy", 50)
            .attr("r", function (d) { return d; })
            .style("fill", "red");</p>

3 个答案:

答案 0 :(得分:1)

假设你的正则表达式没问题应该是:

return preg_replace($pattern,$replacement,$pre_content[1]);//note the second element of the array [1]

答案 1 :(得分:0)

试试这个:

/**
 * Converts a new-line delimited string (with embedded HTML PRE tags) to
 * HTML paragraphs, preserving the newline delimiters within the PRE.
 * @param string $str
 * @return string
 */
function pFormat( $str )
{
    $a = explode( "\n", $str );
    $out = array();
    $isPre = FALSE;
    $lastBlank = FALSE;
    for( $i = 0, $l = count( $a ); $i < $l; $i++ )
    {
        $line = trim( $a[$i] );
        if( empty( $line ) )
        {
            if( $isPre )
            {
                $out[] = "";
            }
            continue;
        }
        if( substr( $line, 0, 4 ) == '<pre' )
        {
            $isPre = TRUE;
            $out[] = $line;
            continue;
        }
        if( substr( $line, 0, 5 ) == '</pre' )
        {
            $out[] = $line;
            $isPre = FALSE;
            continue;
        }
        $out = '<p>' . $line . '</p>';
    }
    return implode( "\n", $out );
}

答案 2 :(得分:0)

根据要求,这应该将双换行转换为段落标记,但预格式化标记内的双换行除外:

$sourcestring="your source string";
echo preg_replace('#\n\n(?!((?!<pre>).)*</pre>)#is','</p><p>',$sourcestring);

在这里进行了测试,使用略微修改的模式来考虑换行符,该工具包括:http://www.myregextester.com/?r=a24b18cf