regex 新行到段落功能

7z5jn7bk  于 2023-06-30  发布在  其他
关注(0)|答案(8)|浏览(125)

我有一个很有趣的函数,我用它来创建新的段落。我使用它而不是nl2br()函数,因为它输出更好的格式化文本。

function nl2p($string, $line_breaks = true, $xml = true) {

$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(
    array("/([\n]{2,})/i", "/([\r\n]{3,})/i","/([^>])\n([^<])/i"),
    array("</p>\n<p>", "</p>\n<p>", '<br'.($xml == true ? ' /' : '').'>'),

    trim($string)).'</p>';

}
问题是,每当我试图创建一个换行符时,它会无意中删除它下面段落的第一个字符。我对正则表达式不够熟悉,无法理解是什么导致了这个问题。

fxnxkyjh

fxnxkyjh1#

下面是另一种不使用正则表达式的方法。请注意,此函数将删除任何单个换行符。

function nl2p($string)
{
    $paragraphs = '';

    foreach (explode("\n", $string) as $line) {
        if (trim($line)) {
            $paragraphs .= '<p>' . $line . '</p>';
        }
    }

    return $paragraphs;
}

如果您只需要在应用中执行一次此操作,并且不想创建函数,则可以轻松地内联完成:

<?php foreach (explode("\n", $string) as $line): ?>
    <?php if (trim($line)): ?>
        <p><?=$line?></p>
    <?php endif ?>
<?php endforeach ?>
kulphzqa

kulphzqa2#

问题是你的比赛单行休息。它匹配换行符之前的最后一个字符和之后的第一个字符。然后将匹配替换为<br>,这样也会丢失这些字符。你需要把它们放在替换物里。
试试这个:

function nl2p($string, $line_breaks = true, $xml = true) {

$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>", '$1<br'.($xml == true ? ' /' : '').'>$2'), trim($string)).'</p>';
else 
    return '<p>'.preg_replace(
    array("/([\n]{2,})/i", "/([\r\n]{3,})/i","/([^>])\n([^<])/i"),
    array("</p>\n<p>", "</p>\n<p>", '$1<br'.($xml == true ? ' /' : '').'>$2'),

    trim($string)).'</p>'; 
}
x6h2sr28

x6h2sr283#

我也写了一个简单的版本:

function nl2p($text)
{
    return '<p>' . str_replace(['\r\n', '\r', '\n'], '</p><p>', $text) . '</p>';
}
krcsximq

krcsximq4#

@Laurent的答案对我来说不起作用-else语句做的是$line_breaks == true语句应该做的事情,它在<br>标记中做了多个换行符,PHP的原生nl2br()已经做了。
下面是我设法使用预期行为得到的结果:

function nl2p( $string, $line_breaks = true, $xml = true ) {

    // Remove current tags to avoid double-wrapping.
    $string = str_replace( array( '<p>', '</p>', '<br>', '<br />' ), '', $string );

    // Default: Use <br> for single line breaks, <p> for multiple line breaks.
    if ( $line_breaks == true ) {
        $string = '<p>' . preg_replace(
            array( "/([\n]{2,})/i", "/([\r\n]{3,})/i", "/([^>])\n([^<])/i" ),
            array( "</p>\n<p>", "</p>\n<p>", '$1<br' . ( $xml == true ? ' /' : '' ) . '>$2' ),
            trim( $string ) ) . '</p>';

    // Use <p> for all line breaks if $line_breaks is set to false.
    } else {
        $string = '<p>' . preg_replace(
            array( "/([\n]{1,})/i", "/([\r]{1,})/i" ),
            "</p>\n<p>",
            trim( $string ) ) . '</p>';
    }

    // Remove empty paragraph tags.
    $string = str_replace( '<p></p>', '', $string );

    // Return string.
    return $string;

}
toe95027

toe950275#

这里有一种方法,它带有一个反向方法,可以将段落替换回常规的换行符,反之亦然。
这些在构建表单输入时很有用。当保存用户输入时,您可能希望将换行符转换为段落标记,但是当编辑表单中的文本时,您可能不希望用户看到任何html字符。然后我们将替换段落回到换行符。

// This function will convert newlines to HTML paragraphs
// without paying attention to HTML tags. Feed it a raw string and it will
// simply return that string sectioned into HTML paragraphs
function nl2p($str) {
    $arr=explode("\n",$str);
    $out='';

    for($i=0;$i<count($arr);$i++) {
        if(strlen(trim($arr[$i]))>0)
            $out.='<p>'.trim($arr[$i]).'</p>';
    }
    return $out;
}

// Return paragraph tags back to line breaks
function p2nl($str)
{
    $str = preg_replace("/<p[^>]*?>/", "", $str);
    $str = str_replace("</p>", "\r\n", $str);
    return $str;
}
ecbunoof

ecbunoof6#

扩展@NaturalBornCamper的解决方案:

function nl2p( $text, $class = '' ) {
    $string = str_replace( array( "\r\n\r\n", "\n\n" ), '</p><p>', $text);
    $string = str_replace( array( "\r\n", "\n" ), '<br />', $string);
    return '<p' . ( $class ? ' class="' . $class . '"' : '' ) . '>' . $string . '</p>';
}

这将通过将双换行符转换为段落来处理双换行符,并通过将单行符转换为<br />来处理单行符

pcrecxhr

pcrecxhr7#

我用close替换双换行符,然后打开新段落</p><p>。剩余的单个换行符转换为<br>标记。

$paragraphs = str_replace ("\r\n\r\n", "</p><p>", $text);
$noLines = str_replace ("\r\n", "<br>", $paragraphs );

如果你有混合的HTML和非HTML内容,你可以在渲染时检查是否存在p标签:

if (str_contains ($blogBody, '<p>')) {
    echo $noLines;
} else {
    echo '<p>'.$noLines.'</p>';
}
c9qzyr3d

c9qzyr3d8#

只要在你的行之间输入这个:

echo '<br>';

这将给予你一个新的路线。

相关问题