正则表达式匹配复杂 server_name 的核心是规范书写:必须以 ~ 或 ~* 开头,点需转义为 .,建议用 ^ 和 $ 锚定,支持捕获组(如 $1)供后续指令引用,并注意其优先级最低,须置于精确匹配和通配符之后,且务必用 nginx -t 验证语法。

用正则表达式匹配复杂的 server_name,核心是让 Nginx 能识别并正确解析 Host 头中不规则、多变或带结构特征的域名,比如含数字编号、下划线、多级可变子域(如 user123.example.com、api_v2.example.net),或需要提取变量用于后续重写、路由、日志等场景。
正则写法必须规范
正则必须以 ~(区分大小写)或 ~*(忽略大小写)开头,否则会被当作普通字符串或非法通配符处理。域名中的点 . 必须转义为 \.,否则会被当成“任意字符”;建议加上 ^ 和 $ 锚定首尾,避免部分匹配。
-
server_name ~^www\d+\.example\.com$;→ 匹配www1.example.com、www999.example.com -
server_name ~*^([a-z0-9_]+)\.api\.example\.(com|net)$;→ 忽略大小写,匹配v1.api.example.com或test_api.example.net,并捕获第一组到$1 - 含特殊字符(如
{、})的正则必须用英文双引号包裹:server_name "~^(?<sub>[a-z0-9\-]+)\.example\.com$";</sub>
捕获组能复用变量
用 (?<name>...)</name> 或 (...) 定义捕获组后,可在 location、rewrite、root 等指令中直接引用 $name 或 。
server_name ~^(?<project>[a-z0-9\-]+)\.dev\.example\.com$;</project>-
root /var/www/dev/$project;→ 请求blog.dev.example.com就自动指向/var/www/dev/blog rewrite ^/(.*)$ /index.php?site=$project&path=$1 last;
注意匹配优先级和性能
正则匹配优先级最低,排在精确匹配和通配符之后。Nginx 会先尝试所有精确名(如 example.com)、再前缀通配符(*.example.com)、再后缀通配符(www.*),最后才轮到正则。如果前面已有通配符兜底,你的正则可能根本不会被触发。
- 把正则放在 server 块靠后位置,确保它不被更宽泛的
*.example.com拦截 - 避免在正则中使用贪婪量词(如
.*)或嵌套重复,影响解析速度 - 每次改完务必运行
nginx -t验证语法,再nginx -s reload - 可用
curl -H "Host: test123.example.com" http://localhost模拟请求测试是否命中
常见易错点
很多配置失败不是逻辑问题,而是书写细节出错:
- 漏掉波浪线:
server_name ^www\..*$❌(被当作文本)→ 应写server_name ~^www\..*$✅ - 点没转义:
server_name ~^api.example.com$❌(.匹配任意字符)→ 应写~^api\.example\.com$✅ - 捕获组未命名却在后续用
$sub:要不加?命名,要不统一用$1、$2 - 正则跨多行或含中文引号、全角符号,导致 nginx 启动报错











