我正在为我的博客改进我的基本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>
答案 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