【问题标题】:How to replace one or two consecutive line breaks in a string?如何替换字符串中的一个或两个连续换行符?
【发布时间】:2010-10-23 09:34:01
【问题描述】:

我正在用 PHP 开发一个single serving site,它只显示访问者发布的消息(理想情况下围绕网站主题)。任何人每小时最多可以发布三条消息。

由于网站只有一页,我想控制每条消息的垂直长度。但是,我确实希望至少部分保留原始消息中的换行符。折衷方案是允许两个换行符,但如果超过两个,则将它们替换为连续两个换行符。 Stack Overflow 实现了这一点。

例如:

Porcupines\nare\n\n\n\nporcupiney.

将改为

Porcupines<br />are<br /><br />porcupiney.

检查换行符的一个棘手方面是它们可能被收集并存储为\r\n\r\n。我考虑过使用nl2br() 将所有换行符转换为&lt;br /&gt;s,但这似乎没有必要。

我的问题:在 PHP 中使用正则表达式(具有 preg_match()preg_replace() 之类的函数),我如何检查连续两个以上换行符的实例(它们之间有或没有空格),然后将它们更改为总共两个换行符?

【问题讨论】:

    标签: php regex pcre line-breaks


    【解决方案1】:
    preg_replace('/(?:(?:\r\n|\r|\n)\s*){2}/s', "\n\n", $text)
    

    【讨论】:

    • 原始回复不符合您的“它们之间有或没有空格”标准。 :)
    • 但是当只有一个换行符时,它会变成两个?它不应该留下一个休息吗?
    • 这个 preg 将不匹配单个换行符。 {2} 限制匹配两个。
    • @QuinnComendant:是的。这是请求行为的一部分。
    • @chaos 感谢您提供此解决方案!当我使用它时,单个换行符总是变成两个换行符。我不得不将 * 更改为 + 以停止替换单个换行符:preg_replace('/(?:(?:\r\n|\r|\n)\s*){2}/s', "\n\n", $text)
    【解决方案2】:

    类似

    preg_replace('/(\r|\n|\r\n){2,}/', '<br/><br/>', $text);
    

    我认为应该可以。虽然我不记得确切的 PHP 语法,但它可能需要更多转义:-/

    【讨论】:

    • 谢谢大卫。我看到您发布的正则表达式的唯一问题是它不容纳换行符之间的空格。
    • 啊,真的...我错过了你提到的换行符之间的空格部分。
    【解决方案3】:

    \R 是与系统无关的escape sequence,它将匹配\n\r\r\n

    因为您想贪婪地匹配 1 或 2 个连续的换行符,您需要使用限制量词 {1,2}

    代码:(Demo)

    $string = "Porcupines\nare\n\n\n\nporcupiney.";
    
    echo preg_replace('~\R{1,2}~', '<br />', $string);
    

    输出:

    Porcupines<br >are<br /><br />porcupiney.
    

    现在,澄清一下为什么/哪里其他答案不正确...

    @DavidZ 无法解释的答案无法替换唯一的换行符 (Demo of failure),因为量词表达式不正确。

    它生成:

    Porcupines\nare<br/><br/>porcupiney.
    

    @chaos 的纯代码答案 (Demo of failure) 可以生成完全相同的结果。正则表达式不仅冗长且错误地实现了量词逻辑,而且还添加了s 模式修饰符。

    s 模式修饰符仅在模式中有点元字符时才对正则表达式产生影响。因为模式中没有.,所以修饰符是无用的,并且正在教研究人员无意义/不正确的编码实践。

    【讨论】:

      【解决方案4】:

      我只是想补充一点,即使它没有直接回答问题,它可能会帮助想要限制换行数的人。 我需要这个来限制论坛帖子中的换行数。我使用了上面选择的答案,并添加了这个:

      //Some pre processing
      $textarea_reply = str_replace("\r", "<br>", $textarea_reply);
      $textarea_reply_splitByLines = explode("<br>", $textarea_reply);
      $textarea_reply = "";
      $line_count = 0;
      $line_limit = 10;
      
      //Re-add the line breaks with a limit of $line_limit
      foreach ($textarea_reply_splitByLines as $line){
          $textarea_reply.= $line." "; 
          if($line_count<$line_limit) $textarea_reply.= "<br>";
          $line_count++;
      }
      

      这无论如何都会将换行数限制为最大数量。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-01-01
        • 2011-05-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-01-19
        相关资源
        最近更新 更多