0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

nginx中的正则表达式和location路径匹配指南

马哥Linux运维 来源:博客园-熊仔其人 2024-09-29 16:02 次阅读

前言,我这里验证的nginx-v1.23.2单机环境下的nginx中的正则表达式、location路径匹配规则和优先级。
先准备好环境,基础配置是这样 nginx/conf/conf.d/host.conf :

server {
    listen 8081;
    server_name  10.90.5.70;

    proxy_connect_timeout 60;
    proxy_read_timeout 600;
    proxy_send_timeout 600;
    proxy_set_header    X-Real-IP           $remote_addr;
    proxy_set_header    X-Forwarded-For     $proxy_add_x_forwarded_for;
    proxy_set_header    X-Forwarded-Proto   "http";
    proxy_set_header    Host                $host;
    proxy_http_version  1.1;
    proxy_set_header    Connection  "";
    proxy_next_upstream error non_idempotent;

    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }
}

下面的案例都是基于以上配置验证的。

一,nginx中的正则表达式

nginx中的正则表达式基本遵循了Regular Expression格式和规则。不同的是,一般以特殊字符代表正则表达式的开始,即标识要用Regular Expression处理其后的字符。
nginx里面可以使用正则表达式的部分可以是 server里,或者location 路径上。

常见的正则表达式的含义

^ :匹配输入字符串的起始位置
$ :匹配输入字符串的结束位置
. :匹配除“
”之外的任何单个字符,若要匹配包括“
”在内的任意字符,请使用诸如“[.
]”之类的模式
d :匹配纯数字
w :匹配字母或数字或下划线或汉字
s :匹配任意的空白符
 :匹配单词的开始或结束

【下面这部分是标注匹配长度(字符数量、重复数量)的】
* :匹配前面的字符零次或多次。如“ol*”能匹配“o”及“ol”、“oll”
+ :匹配前面的字符一次或多次。如“ol+”能匹配“ol”及“oll”、“olll”,但不能匹配“o”
? :匹配前面的字符零次或一次,例如“do(es)?”能匹配“do”或者“does”,”?”等效于”{0,1}”
{n} :重复 n 次
{n,} :重复 n 次或更多次
{n,m} :重复 n 到 m 次

[] :定义匹配的字符范围
[c] :匹配单个字符 c
注意:在括号里面用-表示范围:
[a-z] :匹配 a-z 小写字母的任意一个
[a-zA-Z0-9] :匹配所有大小写字母或数字
() :表达式的开始和结束位置 例如:(jpg|gif|swf|)

| :或运算符
! :非运算符(与其后面的表达式去反运算)
正则表达式里面没有“与运算符”。

 :转义字符,将后面接着的字符标记为一个特殊字符或一个原义字符或一个向后引用。如“
”匹配一个换行符,而“$”则匹配“$”

参考链接:https://www.jb51.net/article/149053.htm

二,location路径匹配规则和优先级

location:用来设置请求的URI。nginx中location配置项是最基础的配置,而且它的配置也稍显复杂。

location匹配规则 与 优先级

默认值 /
语法location [ = | ~ | ~* | ^~ ] uri { ... }
位置 server,location
uri变量是待匹配的请求字符串,可以不包含正则表达式,也可以包含正则表达式。那么:

nginx服务器在搜索匹配location的时候,是先使用不包含正则表达式进行匹配,找到一个匹配度最高的一个,然后在通过包含正则表达式的进行匹配,如果能匹配到直接访问,匹配不到,就使用刚才匹配度最高的那个location来处理请求。

另一种描述,意思是一样的:

location 匹配的优先级(与location在配置文件中的顺序无关)
= 精确匹配会第一个被处理。如果发现精确匹配,nginx停止搜索其他匹配。
普通字符匹配,正则表达式规则和长的块规则将被优先和查询匹配,也就是说如果该项匹配还需去看有没有正则表达式匹配和更长的匹配。
^~ 则只匹配该规则,nginx停止搜索其他匹配,否则nginx会继续处理其他location指令。
最后匹配理带有"~"和"~*"的指令,如果找到相应的匹配,则nginx停止搜索其他匹配;
当没有正则表达式或者没有正则表达式被匹配的情况下,那么匹配程度最高的逐字匹配指令会被使用。

location 优先级官方文档:

1.  Directives with the = prefix that match the query exactly. If found, searching stops.
2.  All remaining directives with conventional strings, longest match first. If this match used the ^~ prefix, searching stops.
3.  Regular expressions, in order of definition in the configuration file.
4.  If #3 yielded a match, that result is used. Else the match from #2 is used.

1.  =前缀的指令严格匹配这个查询。如果找到,停止搜索。
2.  所有剩下的常规字符串,最长的匹配。如果这个匹配使用^〜前缀,搜索停止。
3.  正则表达式,在配置文件中定义的顺序。
4.  如果第3条规则产生匹配的话,结果被使用。否则,如同从第2条规则被使用。

它包含了路径的匹配规则和针对该规则的配置。

location规则按照前导符主要分五类:

代号 前导符 说明
= uri 全字匹配,只有当请求路径和uri完全匹配时,对应的规则才会生效
~ regular 区分大小写的正则匹配
~* regular 不区分大小写的正则匹配
^~ uri 否定正则的路径匹配
url 没有任何前导符的路径匹配

这五类规则,同时存在配置文件中时,按照一定的优先级规则生效。
优先级:( location = ) > ( location 完整路径 ) > ( location ^~ 否定正则 ) > ( location ~* 正则顺序 ) > ( location ~ 区分大小写正则顺序 ) > ( location 部分起始路径 ) > ( / )
优先级:① > ④ > ③ > ② > ⑤

nginx规则决定流程如下图:
wKgZomb5Cb2AbMf0AACDRywOs8w869.png
文字说明:
以下说明非常关键
一、检查请求uri是否与某个=规则匹配,如果有,直接应用规则,终止后续匹配。
二、nginx首先检查所有路径匹配规则配置项,包括"^~"规则和没有前导符号的规则,选择并记住和当前请求uri匹配度最长的配置项。但这个时候,并不会启用相关的配置,而仅仅是记住。
三、判断上一步中选择下来的路径规则是否包含 ^~ ,如果包含,则使用该条规则,终止后续匹配。
四、按配置顺序进行正则表达式检查,匹配到第一条合适的正则表达式时,使用该条规则,终止后续匹配。
五、使用步骤三选择出来的路径匹配规则。

下面以实例属性介绍:

1,不带符号,要求必须以指定模式开始

location指令实例:

server {
    listen 8081;
    server_name 127.0.0.1;
    
   # 不带符号,要求必须以指定模式开始(区分大小写,并且后面带/是有区别的)
   location /aaa {
        default_type text/plain;
        return 200 "access success aaa 

";
   }
}

# 能匹配到:
http://127.0.0.1:8081/aaa
http://127.0.0.1:8081/aaa/
http://127.0.0.1:8081/aaadef
http://127.0.0.1:8081/aaa/def/
http://127.0.0.1:8081/aaa?p1=TOM

# 不能匹配到(大小写区分):
http://127.0.0.1:8081/Aaa

# 如果规则(后面跟/目录符号) location /aaa/ { 则只能匹配到下面两行:
http://127.0.0.1:8081/aaa/
http://127.0.0.1:8081/aaa/def/

如图:
wKgZomb5CdyAOexUAABehTzGzLQ334.png

2,= 用于不包含正则表达式的uri前,必须与指定的模式精确匹配

实测,等于号后面有或没有空格不影响效果。location指令实例:

server {
    listen 8081;
    server_name 127.0.0.1;
    
   # = : 用于不包含正则表达式的uri前,必须与指定的模式精确匹配(区分大小写,并且后面带/是有区别的)
   location = /bbb {
        default_type text/plain;
        return 200 "access success bbb 

";
   }

}

# 能匹配到:
http://127.0.0.1:8081/bbb
http://127.0.0.1:8081/bbb?p1=TOM

# 不能匹配到(大小写区分):
http://127.0.0.1:8081/bbb/
http://127.0.0.1:8081/bbbcd
http://127.0.0.1:8081/Bbb

如图:
wKgZomb5CeiAXJa_AACHwiYnVhU184.png

3,包含正则表达式的

~ :用于表示当前uri中包含了正则表达式,并且区分大小写
~*: 用于表示当前uri中包含了正则表达式,并且不区分大小写
换句话说,如果uri包含了正则表达式,需要用上述两个符合来标识
^~: 用于不包含正则表达式的uri前,功能和不加符号的一致,唯一不同的是,如果模式匹配,那么就停止搜索其他模式了。(可用它提升优先级)

含正则表达式的location指令,实例一:

server {
    listen 8081;
    server_name 127.0.0.1;

   # ~ :用于表示当前uri中包含了正则表达式,并且区分大小写
   # 正则表达式:区分大小写,以/abc开头,以1个字母或数字或下划线或汉字结束的
   location ~^/eeew$ {
        default_type text/plain;
        return 200 "access success. 000 Regular expression matched: eee  

";
   }
}

# 能匹配到:
http://127.0.0.1:8081/eeeb
http://127.0.0.1:8081/eeeB
http://127.0.0.1:8081/eee2

# 不能匹配到(大小写区分):
http://127.0.0.1:8081/eee
http://127.0.0.1:8081/Eee
http://127.0.0.1:8081/eee/
http://127.0.0.1:8081/eeedef
http://127.0.0.1:8081/eee/def/
http://127.0.0.1:8081/eee?p1=TOM

如图:
wKgaomb5CfSAOia4AABWApWC5sg421.png

含正则表达式的location指令,实例二:

server {
    listen 8081;
    server_name 127.0.0.1;

   # ~*: 用于表示当前uri中包含了正则表达式,并且不区分大小写
   # 正则表达式:不区分大小写,以/abc开头,以字母或数字或下划线或汉字结束的
   location ~*^/dddw$ {
        default_type text/plain;
        return 200 "access success. 111 Regular expression matched: ddd  

";
   }
}

# 能匹配到:
http://127.0.0.1:8081/dddb
http://127.0.0.1:8081/dddB
http://127.0.0.1:8081/ddd2
http://127.0.0.1:8081/DddH

# 不能匹配到(大小写区分):
http://127.0.0.1:8081/ddd
http://127.0.0.1:8081/Ddd
http://127.0.0.1:8081/ddd/
http://127.0.0.1:8081/ddddef
http://127.0.0.1:8081/ddd/def/
http://127.0.0.1:8081/ddd?p1=TOM

如图:
wKgaomb5CgOASs4mAAClwuYrXsQ879.png

不包含正则表达式的location指令,实例三:

server {
    listen 8081;
    server_name 127.0.0.1;

   # ^~: 用于不包含正则表达式的uri前,功能和不加符号的一致,唯一不同的是,如果模式匹配,那么就停止搜索其他模式了,可用于提升优先级。(区分大小写,并且后面带/是有区别的)
   location ^~ /fff {
        default_type text/plain;
        return 200 "access success. Non Regular expression matched: fff  

";
   }
}

# 能匹配到:
http://127.0.0.1:8081/fff
http://127.0.0.1:8081/fff/
http://127.0.0.1:8081/fffdef
http://127.0.0.1:8081/fff/def/
http://127.0.0.1:8081/fff?p1=TOM

# 不能匹配到(大小写区分):
http://127.0.0.1:8081/Fff
http://127.0.0.1:8081/pp/fff

# 如果规则(后面跟/目录符号) location /fff/ { 则只能匹配到下面两行:
http://127.0.0.1:8081/fff/
http://127.0.0.1:8081/fff/def/

如图:
wKgZomb5Cg6ANZd9AACWe8uQpc0944.png

定义一个命名的 location

用"@" 定义一个命名的 location,使用在内部定向时,例如:error_page, try_files
@location 例子:

# 示例:404错误页将被内部重定向
    error_page 404 = @fetch;
    location @fetch(
        proxy_pass http://fetch;
    )

# 类似案例:
    error_page  404              /404.html;
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

链接:https://www.cnblogs.com/xiongzaiqiren/p/16968651.html

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 字符串
    +关注

    关注

    1

    文章

    567

    浏览量

    20391
  • nginx
    +关注

    关注

    0

    文章

    141

    浏览量

    12127
  • 正则表达式
    +关注

    关注

    0

    文章

    26

    浏览量

    3463

原文标题:nginx中的正则表达式和location路径匹配指南

文章出处:【微信号:magedu-Linux,微信公众号:马哥Linux运维】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    什么是正则表达式正则表达式如何工作?哪些语法规则适用正则表达式

    正则表达式又称规则表达式(Regular Expression,在代码中常简写为 regex、regexp 或 RE),是一种用于匹配、查找、替换文本的强大工具。它能够以特定的模式匹配
    的头像 发表于 11-03 14:41 1953次阅读
    什么是<b class='flag-5'>正则表达式</b>?<b class='flag-5'>正则表达式</b>如何工作?哪些语法规则适用<b class='flag-5'>正则表达式</b>?

    匹配字符串-----正则表达式的使用

    关于:匹配字符串-----正则表达式的使用和大家分享一下
    发表于 03-20 11:11

    shell正则表达式学习

    正则表达式在计算机科学,是指一个用来描述或者匹配一系列符合某个句法规则的字符串的单个字符串。在很多文本编辑器或其他工具里,正则表达式通常被用来检索和/或替换那些符合某个模式的文本内容
    发表于 07-25 17:18

    求助,匹配正则表达式使用问题

    求助,我在使用匹配正则表达匹配visi串口传回的数据时候,一直无法匹配成功。我怀疑是我的正则表达式
    发表于 03-29 21:19

    正则表达式在Vivado约束文件的应用

    文件匹配目标的时候,在可行的情况下更倾向于使用正则表达式。本文就介绍一下我常使用的正则表达式和一些在Vivado应用的特殊之处,同时也有
    发表于 01-26 07:03

    正则表达式以及实用的匹配规则概述

    )在正则表达式,可以使用圆括号对表达式进行分组。在匹配完成后,就可以使用分组编号来对圆括号的内容进行提取。默认情况下,整个
    发表于 09-16 14:23

    正则表达式匹配

    正则表达式是描述文本模式的表示法,它可以有效地构造一种用于模式匹配的专用语言。虽然正则表达式可以有多种不同的形式,但它们都有着共同的特点:模式的大多数字符都
    发表于 10-29 13:21 0次下载

    深入浅出boost正则表达式

    什么是正则表达式正则表达式是一种用来描述一定数量文本的模式。Regex代表Regular Express. 如果您不知道什么是正则表达式,请看这篇文章:深入浅出之正则表达式
    发表于 09-08 18:09 9次下载

    Python正则表达式的学习指南

    本文介绍了Python对于正则表达式的支持,包括正则表达式基础以及Python正则表达式标准库的完整介绍及使用示例。本文的内容不包括如何编写高效的正则表达式、如何优化
    发表于 09-15 08:00 0次下载
    Python<b class='flag-5'>正则表达式</b>的学习<b class='flag-5'>指南</b>

    Python正则表达式指南

    本文介绍了Python对于正则表达式的支持,包括正则表达式基础以及Python正则表达式标准库的完整介绍及使用示例。本文的内容不包括如何编写高效的正则表达式、如何优化
    发表于 03-26 09:13 10次下载
    Python<b class='flag-5'>正则表达式</b><b class='flag-5'>指南</b>

    python正则表达式的常用函数

    编译正则表达式模式,返回一个正则对象的模式。(可以把那些常用的正则表达式编译成正则表达式对象,这样可以提高一点效率。)
    的头像 发表于 03-18 16:12 1709次阅读

    Linux入门之正则表达式

    正则表达式是用来表达字符串匹配模式的方法,利用正则表达式,可以让我们轻易地实现对目标字符串的**查找**、**删除**、**替换**等操作。
    的头像 发表于 05-12 15:31 764次阅读
    Linux入门之<b class='flag-5'>正则表达式</b>

    shell脚本基础:正则表达式grep

    在Linux上有许多命令可以使用正则表达式,其中最常见的是grep命令和sed命令。正则表达式有多种类型,每种类型可以使用的元字符类型不同。最常见的是基本正则表达式和扩展
    的头像 发表于 05-29 09:29 1090次阅读
    shell脚本基础:<b class='flag-5'>正则表达式</b>grep

    Python正则表达式

    哈喽大家好,我是了不起,今天给大家讲Python正则表达式 在Python正则表达式是一种强大的文本处理工具,它可以用来匹配、搜索、
    的头像 发表于 06-21 16:52 877次阅读

    linux正则表达式匹配字符串

    在Linux操作系统正则表达式是一种强大的模式匹配工具,它可以用于在文本查找、替换和筛选特定的字符串。准确掌握正则表达式的语法和常见应
    的头像 发表于 11-23 10:26 592次阅读