Nginx 正则表达式详解
在 Nginx 中,正则表达式主要用于 location 指令来匹配客户端请求的 URI,从而实现精细化的请求路由和处理。
location 指令是 Nginx 路由的核心,它决定了如何处理一个请求。不同的匹配模式有不同的优先级。
Nginx 的 location 匹配规则其实有一套严格的**"优先级算法"**。
简单来说:Nginx 会优先检查"路径前缀匹配",如果前缀匹配带有 ^~ 标记,则直接忽略正则;否则,Nginx 会继续检查正则表达式。
为了让你彻底明白,我将匹配规则拆解为**"三个阶段"**,并总结了一个判断逻辑表。
核心结论:什么时候是正则,什么时候是路径?
| 场景 | 判定逻辑 | 结果 |
|---|---|---|
| 精确路径 | 请求 URI 与 location = /path 完全一致 |
路径匹配 (优先级最高,立即结束) |
| 特殊前缀 | 请求 URI 以 location ^~ /path 开头 |
路径匹配 (优先级高,强制停止后续正则检查) |
| 普通前缀 | 请求 URI 以 location /path 开头 |
暂存 。Nginx 会记下这个匹配,但继续去检查正则。如果正则没匹配上,才用这个。 |
| 正则表达式 | 请求 URI 符合 location ~ pattern |
正则匹配 (只有当"特殊前缀"未命中,且正则按顺序第一个匹配时生效) |
🔍 详细匹配流程(按执行顺序)
当你发起一个请求(例如 /images/logo.png)时,Nginx 内部是这样一步步处理的:
第一步:检查"精确匹配" (=)
- 规则 :
location = /images/logo.png - 行为 :如果 URI 和配置完全一模一样 ,直接选中,匹配结束。
- 注意:这是最高优先级,不管后面有什么正则,只要这里匹配了,后面都不看。
第二步:检查"普通前缀" (/) 和 "特殊前缀" (^~)
Nginx 会遍历所有非正则的 location(即不带 ~ 的),寻找最长的那个匹配前缀。
-
情况 A:命中了
^~- 配置:
location ^~ /images/ - 行为 :一旦匹配成功,Nginx 立即停止 搜索。正则表达式将被完全忽略。
- 用途:通常用于静态资源目录,为了性能,不让 Nginx 浪费时间去跑正则。
- 配置:
-
情况 B:命中了普通前缀 (无修饰符)
- 配置:
location /images/ - 行为 :Nginx 会把这个路径暂时记下来 (作为备选),但不会停止,它会继续进入第三步去检查正则。
- 配置:
第三步:检查"正则表达式" (~ 或 ~*)
- 前提 :只有当第二步没有命中
^~时,才会执行这一步。 - 行为 :Nginx 按照配置文件中从上到下的顺序,逐个测试正则规则。
- 结果 :一旦命中第一个正则规则,立即停止搜索并使用该配置。
- 兜底:如果所有正则都没命中,则使用第二步中记下来的那个"普通前缀"配置。
💡 举例说明(避坑指南)
假设你的配置如下:
# 1. 普通前缀匹配
location /static/ {
# 配置 A
}
# 2. 正则匹配 (看起来能匹配 .jpg)
location ~ \.jpg$ {
# 配置 B
}
# 3. 特殊前缀匹配
location ^~ /static/images/ {
# 配置 C
}
场景 1:请求 /static/test.jpg
- 精确匹配:无。
- 前缀检查 :命中
location /static/。记下它,继续检查正则。 - 正则检查 :命中
location ~ \.jpg$。 - 结果 :使用 配置 B(正则优先于普通路径)。
场景 2:请求 /static/images/logo.jpg
- 精确匹配:无。
- 前缀检查 :
- 命中
location /static/。 - 命中
location ^~ /static/images/。 - 因为
^~优先级高且带有"停止"指令。
- 命中
- 结果 :使用 配置 C (
^~强制拦截,正则失效)。
location 匹配规则与优先级
| 匹配模式 | 说明 | 优先级 |
|---|---|---|
location = /path |
精确匹配:URI 必须与指定路径完全相同。 | 最高 |
location ^~ /path |
前缀匹配 :匹配以指定路径开头的 URI,匹配成功后不再进行正则匹配。 | 高 |
location ~ pattern |
正则匹配:使用区分大小写的正则表达式进行匹配。 | 中 |
location ~* pattern |
正则匹配:使用不区分大小写的正则表达式进行匹配。 | 中 |
location /path |
普通前缀匹配:匹配以指定路径开头的 URI。 | 低 |
location / |
通用匹配:匹配所有请求,作为默认配置。 | 最低 |
优先级规则总结:
精确匹配 (=) > 前缀匹配 (^~) > 正则匹配 (~, ~*,按配置文件顺序) > 普通前缀匹配 > 通用匹配 (/)。
在 Nginx 的 location 配置中,只要是以 ~ 或 ~* 开头的,就一定是正则表达式匹配。
Nginx Location 修饰符速查表
| 修饰符开头 | 匹配模式 | 说明 |
|---|---|---|
~ |
正则匹配 | 区分大小写 (例如 ~ /A 匹配 /A 但不匹配 /a) |
~* |
正则匹配 | 不区分大小写 (例如 ~* /A 既匹配 /A 也匹配 /a) |
= |
路径匹配 | 精确路径匹配(必须完全一致) |
^~ |
路径匹配 | 前缀路径匹配(匹配到后停止正则搜索) |
| 无修饰符 | 路径匹配 | 普通前缀路径匹配(例如 location /api) |
💡 两个关键点
-
区分大小写:
- 如果你写
location ~ /Images/,它只能匹配/Images/,无法匹配/images/。 - 如果你想忽略大小写,必须加上
*,写成location ~* /Images/。
- 如果你写
-
优先级:
- 正则匹配(
~/~*)的优先级 低于=和^~。 - 正则匹配的优先级 高于 普通路径匹配(无修饰符)。
- 正则匹配(
总结: 看到 ~ 开头,就是正则;看到 ~* 开头,就是忽略大小写的正则。