preg_match() 适用于“是/否”类格式校验,返回1/0/false,需注意锚定、修饰符、错误处理;preg_replace() 替换失效常因分隔符冲突、贪婪匹配或缺失u修饰符;应规避灾难性回溯、过度用.*及未限长问题。

preg_match() 是你验证字符串是否符合规则的第一道关卡,不是万能的,但绝大多数表单校验、格式判断场景,用它就够了——别一上来就写 preg_match_all() 或硬套捕获组。
什么时候该用 preg_match() 而不是其他函数
它只找第一个匹配,返回 1(成功)、0(没找到)或 false(出错),适合「是/否」类判断:
- 邮箱、手机号、身份证号格式校验 —— 只需确认整体结构对不对,不需要提取子字段
- 路由匹配(如
/user/(d+)判断请求路径是否匹配某类接口) - 敏感词存在性检查(
if (preg_match('/(密码|admin)/i', $input)))
容易踩的坑:
- 忘记加
^和$:比如/d{6}/会把"abc123456def"也判为“6位数字”,实际你要的是完整6位 —— 应写成/^d{6}$/ - 误用修饰符:
g在preg_match()中无效(PHP 不支持g修饰符),全局匹配得换preg_match_all() - 没处理
false:当$pattern语法错误(比如括号不配对),函数直接返回false,而不是0,用=== false显式判断更安全
preg_replace() 替换时,为什么有时替换不生效
常见现象:写了 preg_replace('/old/', 'new', $str),但输出还是原字符串。原因往往不在逻辑,而在模式本身:
- 未转义特殊字符:想替换字面量
https://,却写成'/https://'—— 斜杠触发了定界符冲突,应改用其他分隔符,如'#https?://#'或转义'/https?:\/\//' - 量词太“贪心”:如
/(<div>.*)/ 在含多个 <code>div的 HTML 中,会跨标签匹配到最末尾的











