m修饰符仅扩展^和$的匹配位置:^可匹配字符串开头及每个\n后,$可匹配字符串末尾及每个\n前;它不改变.、\s、\w行为,也不实现跨行匹配,需配合^或$才有意义,且换行符须由双引号或heredoc解析。

PHP中m修饰符只改^和$的匹配位置
m不是让正则“跨行匹配”,也不影响.、\s或\w的行为。它唯一作用是:让^除了匹配整个字符串开头,还能匹配每个\n之后的位置;让$除了匹配整个字符串末尾,还能匹配每个\n之前的位置。
前提是字符串里真有换行符——单引号字符串里的\n是字面量两个字符,不会被解析为换行;双引号或heredoc才有效。
不加m时^和$只能锚定全文
比如字符串"line1\nline2\nline3":
- 用
/^line2$/完全不匹配——因为^只认最开头,$只认最后结尾 - 用
/^line2$/m能匹配第二行的"line2"
注意:m单独启用没意义,必须配合^或$才体现效果。写/abc/m和/abc/行为完全一样。
立即学习“PHP免费学习笔记(深入)”;
m和s经常一起用,但解决的是不同问题
常见误区是以为m能让.匹配换行符——其实不能。s才是干这个的。
-
/^ERROR.*$/m:匹配每行以ERROR开头的内容,但.仍不跨行 -
/^ERROR.*$/ms:既逐行锚定,又允许.吞掉中间的换行符(比如匹配从某行ERROR到下一行END之间的所有内容) -
preg_match_all()必须搭配m才能提取多行中的行首/行尾模式,否则只可能匹配第一行或最后一行
容易忽略的兼容性细节
PHP的m行为和Perl一致,但和JavaScript的/m不完全等价:
- PHP中
$在m模式下仍会匹配\n前的位置,即使后面还有内容(如"abc\n"里的$匹配n前) - 如果字符串末尾没有
\n,$依然能匹配到字符串真正结尾 -
m对\A和\Z无影响——它们始终只锚定整个字符串起止
真正难调试的点往往不在m本身,而在于你默认以为.能跨行,结果发现没配s,或者用了单引号导致换行根本不存在。



















