You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP多行模式正则匹配捕获内容意外包含换行符问题排查

问题根因

你遇到的问题源于PHP PCRE正则引擎对行结束符的默认处理规则:

  1. PCRE中.默认仅排除换行符\n(LF),回车符\r(CR)会被.正常匹配。你的测试数据使用Windows风格换行\r\n,第一行实际内容为!!! hello\r\n
  2. 多行模式(m修饰符)下,PCRE默认仅将\n作为行结束标记,$锚点默认只匹配\n之前的位置。因此.*会贪婪匹配到\n前的所有内容,包含末尾的\r,你实际捕获到的是hello\r而非hello\r\n
  3. 输出时\r会被多数文本渲染环境当作回车/换行处理,因此会看到第二个|出现在新行,看起来像是捕获了换行符。

你修改为[a-z]*后能正常输出,正是因为\r不在小写字母匹配范围内,捕获到hello后就停止了,不会包含末尾的\r;限定结尾为o的版本同理。

解决方案

以下任意一种方案都可以解决该问题:

  • 方案1:直接在捕获组中排除所有换行相关字符,从根源上避免匹配到\r
    preg_replace('/^!!! ([^\r\n]*)/m', '|$1|', $content);
    
  • 方案2:在正则开头添加(*CRLF)标记,告诉PCRE引擎将\r\n作为行结束标记,此时$锚点会匹配\r\n之前的位置,不会把\r留给捕获组
    preg_replace('/(*CRLF)^!!! (.*)$/m', '|$1|', $content);
    
  • 方案3:先统一将内容的换行符转为Unix风格的\n,再执行正则匹配
    $content = str_replace("\r\n", "\n", $content);
    preg_replace('/^!!! (.*)$/m', '|$1|', $content);
    

内容的提问来源于stack exchange,提问作者Tarindel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 09:48:03