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

如何用PCRE2正则匹配含“cat”的段落(PHP≥7.3)

解决PHP≥7.3中PCRE2正则匹配含指定单词的段落问题

问题背景

需要匹配文本中所有包含单词cat的段落,段落以两个连续换行分隔,段落内允许单个换行但不能有两个连续换行。之前尝试的((?!\n\n).)*(cat)和\n\n.*(?=cat)cat.*\n\n均无法正常工作,前者无法跨单行匹配,后者仅能捕获单行内容。

正确正则表达式

使用PCRE2的DOTALL模式结合边界匹配,正则如下:

(?s)(?:^|\n\n)(?!\n)(.*?cat.*?)(?=\n\n|$)

正则说明

  • (?s):开启DOTALL模式,让.可以匹配换行符,支持捕获段落内的单行换行
  • (?:^|\n\n):匹配段落的起始边界,要么是文本开头,要么是两个连续换行(非捕获组,避免多余分组)
  • (?!\n):排除空段落(防止匹配多个连续换行产生的空行)
  • (.*?cat.*?):非贪婪匹配包含cat的内容,确保只捕获当前段落,不会跨到下一个段落
  • (?=\n\n|$):正向预查段落结束边界,要么是两个连续换行,要么是文本结尾

PHP代码示例

$text = <<<'TEXT'
Paragraph 1 wepfowfpo
fww efwf

Paragraph 2 wefwf32321
!@d r33tcat54, 333!..

Paragraph 3 4t4t022
-`121231ere3r3cat342232
$ 4t0g cat rdwd203  
$$333

Paragraph 4 222cocdo3
TEXT;

// 编译正则
$pattern = '/(?s)(?:^|\n\n)(?!\n)(.*?cat.*?)(?=\n\n|$)/';
// 匹配所有符合条件的段落
preg_match_all($pattern, $text, $matches);

// 输出结果
foreach ($matches[1] as $paragraph) {
    echo $paragraph . "\n";
}

结果验证

运行上述代码后,将输出:

Paragraph 3 4t4t022
-`121231ere3r3cat342232
$ 4t0g cat rdwd203  
$$333

为什么之前的正则失效?

  • ((?!\n\n).)*(cat):未开启DOTALL模式,.无法匹配换行,只能捕获单行内容;且未处理段落边界,可能匹配不完整的段落片段
  • \n\n.*(?=cat)cat.*\n\n:同样未支持跨换行匹配,且无法处理文本开头/结尾的段落,仅能捕获被两个换行包裹的单行内容

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 12:37:42