【问题标题】:preg_replace that only removes more than 2 lines [duplicate]preg_replace 仅删除超过 2 行 [重复]
【发布时间】:2021-08-13 16:13:53
【问题描述】:

我需要使用 preg_replace 命令只删除超过 2 行。但是我的代码删除了所有行。我正在使用:

$content = preg_replace("/\r\n/", "\n", $_POST['content']);

输入:

Line1
Line2

Line3



Line4

输出:

Line1
Line2
Line3
Line4

我想要:

Line1
Line2

Line3

Line4

所以代码必须只删除文本中多余的行。我可以使用不同类型的代码。

【问题讨论】:

标签: php preg-replace


【解决方案1】:

你可以使用:

echo preg_replace('/(\R)(\R){2,}/', "$1$2", $str);

Demo & explanation

【讨论】:

    【解决方案2】:

    用其中两个替换三个或多个一个:

    ... = preg_replace('/((\R)\2)\2+/', '\1', ...);
    

    在哪里

    • \R 构成一行(换行符)
    • (\R)one 的子模式
    • ((\R)\2)two of one 的子模式,通过反向引用捕获替换
    • \2+ 是一个或多个 one 通过反向引用

    这使得 one 中的三个或更多替换为 one 中的两个。

    比较:用一个替换两个或多个一个,因为它更简单一些(and exists for reference already):

    ... = preg_replace('/(\R)\1+/', '\1', ...);
    

    特别是在您的问题的背景下:

    将后跟一个或多个换行符的两个换行符替换为前两个换行符,因为任何换行符都可能不同:

    ... = preg_replace('/(\R\R)\R+/', '\1', ...);
    

    理由:

    但我的代码删除了所有行。

    ... = preg_replace("/\r\n/", "\n", ...);

    是的,它可能看起来如此,但它实际上将每个 Carriage-Return + Line-Feed (CRLF; \r\n) 替换为换行符 (LF; \n)。

    因此,它删除了所有回车符(CR;\r)并保留换行符(LF;\n)。

    这只是为了更好地理解您的问题。重要的学习是你绝对不想用字符串"\n" 替换它 - 你如何写 - “删除所有行”

    然后,解决这个问题的方法是在您引用模式中的那些时,您想用 "\r\n" 替换有根据的猜测。

    剩下的和这个问题差不多:

    这表明了这样的模式:

    ... = preg_replace('/__+/', '_', ...);
    # or:
    ... = preg_replace('/(_)\1+/', '\1', ...);
    

    但是要替换两个或更多。您想将三个或更多替换为两个连续留下。

    使用前面的假设替换为"\r\n" (CRLF),这将是用其中的两个替换其中的三个或更多:

    ... = preg_replace('/\r\n\r\n(\r\n)+/', "\r\n\r\n", ...);
    # or:
    ... = preg_replace('/(\r\n)\1\1+/', '\1\1', ...);
    

    在您的变体中,新行由两个字符(CR 和 LF)组成,要替换的“字符”实际上是 sub-pattern(由括号构成)。

    使用反向引用扩展最后一个示例,使其更符合引用问题中的 to 或 more 情况:

     ... = preg_replace('/(\r\n)\1\1+/', '\1\1', ...);
    

    然后创建另一个反向引用来替换,因为你想用两个替换三个或更多:

     ... = preg_replace('/((\r\n)\2)\2+/', '\1', ...);
    

    现在回到开头,仍然不清楚在您的主题中实际上什么构成了新行,但仍有可能不是“\r\n”而是其他变体(例如每个单独的“\r”或“ \n") 可能是这样。由于使用正则表达式处理行很常见,幸运的是有一个专用的escape-sequence 来处理所有这些:

    \R
    
    line break: matches \n, \r and \r\n
    

    (此描述为摘要)

    使用\R 代替(\r\n) 来生成模式:

     ... = preg_replace('/(\R{2})\R+/', '\1', ...);
     # or:
     ... = preg_replace('/((\R)\2)\2+/', '\1', ...);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-07-28
      • 1970-01-01
      • 2017-06-13
      • 2022-10-21
      • 2018-08-11
      • 1970-01-01
      • 1970-01-01
      • 2015-07-07
      相关资源
      最近更新 更多