PHP正则匹配指定前缀URL路径 排除特定子路径的正确写法
PHP匹配指定前缀URL、排除指定子路径的正则写法
原有正则失效原因
你写的正则#^/admin(?<!/auth)/.*$#使用了负向后视断言,但断言位置紧接在/admin字符串之后,该位置向前回溯的固定长度范围内是/admin本身,永远不可能匹配到/auth字符串,因此断言完全不生效,无法实现排除效果。
正确正则写法(单排除路径场景)
匹配所有/admin前缀路径、排除/admin/auth前缀路径的正则如下:
#^/admin(?!/auth)(/.*)?$#
规则说明
^/admin:强制匹配路径起始位置的/admin前缀(?!/auth):负向前瞻断言,校验/admin之后的紧邻内容不能以/auth开头,直接拦截所有/admin/auth前缀的路径(/.*)?:匹配/admin之后的后续路径内容,加?是为了兼容匹配/admin本身这个根路径;如果业务要求/admin后必须带子路径,直接去掉?写成/.*即可- 首尾的
#是PHP正则推荐分隔符,无需对路径内的/做额外转义,写法更简洁
匹配效果验证
- 符合匹配要求的路径:
/admin/admin/dashboard/admin/user/setting
- 会被拦截的不符合路径:
/admin/auth/admin/auth/login/admin/auth/reset-password
多排除路径扩展写法
如果需要同时排除多个子路径,比如额外排除/admin/public、/admin/debug,直接在负向前瞻内用|分隔多个排除规则即可:
#^/admin(?!/auth|/public|/debug)(/.*)?$#
更严谨的路径段匹配版本
如果要避免误拦截前缀相似的路径(比如/admin/authentication不属于/admin/auth子路径,但会被上面的基础规则误判),可以给排除规则增加路径段结束校验,只有完整匹配路径段的内容才会被排除:
#^/admin(?!/auth(/|$))(/.*)?$#
这个版本只会排除/admin/auth本身、以及/admin/auth/开头的子路径,不会影响/admin/authentication这类同前缀不同段的路径。
内容的提问来源于stack exchange,提问作者MSD
相关产品推荐
相关产品推荐

