php正则生效需“写对+选对函数+控修饰符+防回溯”:preg_match只找首个匹配,preg_match_all穷尽所有;^$默认匹配全文首尾,需/m才逐行;定界符冲突须换用#或~;中文须加u修饰符;贪婪量词需加?转非贪婪;\d\s\w在u下才支持unicode。

PHP正则表达式不是“写对就能用”,而是“写对 + 选对函数 + 控制修饰符 + 防住回溯”才真正生效。直接套用网上现成的邮箱或手机号正则,常在中文、特殊符号、边界空格或长文本时 silently 失败。
preg_match 和 preg_match_all 的行为差异必须分清
两者都用 preg_match() 或 preg_match_all() 调用,但返回逻辑完全不同:前者只找第一个匹配就停,后者穷尽所有可能。实际开发中容易误用导致漏匹配。
-
preg_match()返回1(匹配)或0(不匹配),$matches只含首个匹配结果(含完整匹配和捕获组) -
preg_match_all()返回匹配总次数,$matches[0]是全部完整匹配,$matches[1]起才是各捕获组的全部结果 - 若正则含
^和$,preg_match()会严格检查整个字符串;而preg_match_all()在默认单行模式下,^/$仍只匹配整体首尾,不是每行——这点常被忽略 - 想让
^/$对每行生效?必须加m修饰符:/pattern/m
定界符选错会导致解析失败或转义灾难
PHP 正则必须用成对定界符包裹,如 /pattern/。但定界符不能是字母、数字或反斜线 \,且一旦选定,内部出现该字符就必须转义。
- 常见错误:
"/https:\/\/example\.com/"—— 这里/既是定界符又是 URL 中的字符,导致语法断裂;应改用#https://example\.com#或~https://example\.com~ - 中文场景下推荐用
u修饰符:/[\x{4e00}-\x{9fff}]+/u,否则 UTF-8 多字节字符会被拆成乱码匹配 - 避免在模式里硬写大量
\/,优先换定界符;尤其处理路径、URL、JSON 字符串时更明显
贪婪匹配默认开启,不加 ? 就容易吃掉不该吃的内容
量词 *、+、{n,} 默认是贪婪的,会尽可能多地匹配。这在提取标签、括号内容或日志字段时极易越界。
- 比如匹配 HTML 标签:
/<div>.*/ 在 <code>"<div>A</div>B<div>C</div>"中会匹配整个字符串,而非两个独立div—— 因为.*吞掉了中间的











