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

PHP中preg_match_all匹配失败,但在线正则测试器可成功

问题分析与解决方案

首先咱们得搞清楚为啥regex101里测试成功,但PHP里却匹配不到——核心问题出在m修饰符的适用场景,以及你测试时和PHP代码里字符串结构的差异上。

问题根源

你在regex101测试时,大概率是把每个|Test|放在了单独的行里(比如每行一个|Test|),这时候/^\|.*\|$/m的^和$在多行模式下会匹配每行的开头和结尾,自然能命中目标。但你的PHP代码里的字符串是一整行的:

$str = 'Why is this not working? |Test| |Test| |Test| |Test| ';

这里所有的|Test|都挤在同一行中,既不在整个字符串的开头(^匹配的是Why的位置),也不在整个字符串的结尾($匹配的是最后的空格位置),加了m修饰符也没用——因为整个字符串里没有换行,m修饰符根本没机会发挥作用。

两种解决方案(根据你的实际需求选择)

1. 如果你确实想匹配「单独一行的|开头|结尾内容」

那需要让目标内容处于单独的行中,也就是给字符串加上换行符,比如:

$re = '/^\|.*\|$/m';
$str = "Why is this not working?\n|Test|\n|Test|\n|Test|\n|Test| ";
preg_match_all($re, $str, $matches, PREG_SET_ORDER, 0);
var_dump($matches);

这时候m修饰符会生效,^匹配每个换行后的行首,$匹配换行前的行尾,就能匹配到那几行|Test|了。

2. 如果你只是想匹配同一行中「被|包裹的子串」

那完全不需要^、$和m修饰符,直接匹配所有被|包裹的内容即可:

$re = '/\|[^|]*\|/'; // [^|]* 匹配任意非|的字符,避免错误匹配跨多个|的内容
$str = 'Why is this not working? |Test| |Test| |Test| |Test| ';
preg_match_all($re, $str, $matches, PREG_SET_ORDER, 0);
var_dump($matches);

这个正则会匹配所有像|Test|这样的子串,不管它们在一行的哪个位置。

补充:PHP中m修饰符的作用

再啰嗦一句,m修饰符的本质是改变^和$的匹配范围:

  • 默认模式:^匹配整个字符串的开头,$匹配整个字符串的结尾
  • 多行模式(加m):^匹配每行的开头(即\n之后的位置),$匹配每行的结尾(即\n之前的位置)
    只有当字符串里包含换行符时,m修饰符才会有实际效果哦。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:44:42