在编写用于NGINX的正则表达式(regex)时,我想到了一种方法,可以直接在实际的NGINX配置中轻松测试正则表达式。(该正则表达式测试工具同样适用于NGINX Open Source和NGINX Plus。为便于阅读,本文将二者统称为NGINX。)
正则表达式支持是NGINX的一项强大功能,但正则表达式可能很复杂,很难正确编写,尤其是在不经常使用的情况下。NGINX允许在配置的多个部分使用正则表达式,例如location、map、rewrite和server_name。本文介绍的测试工具适用于location和map中的正则表达式。
还有其他免费的在线正则表达式测试工具,适用于大多数正则表达式,但NGINX使用了一些针对Web应用优化的非标准简写。例如,与标准正则表达式不同,URI中的正斜杠(/)无需转义。此外,在map中使用正则表达式时,需要指定匹配后要设置的值。使用其他正则表达式测试工具时,可能需要修改正则表达式;对于map,则可能需要推断将设置的值。另外,最好能在实际环境中使用实际的正则表达式引擎进行测试。
注意事项:
- NGINX使用Perl兼容正则表达式(PCRE)。本文假定读者对NGINX和正则表达式都有基本了解。如何构建正则表达式不在本文讨论范围内,很遗憾,我们无法在评论区进一步回答相关问题。许多网站提供用于构建正则表达式的工具或文档。以下是我们认为有用的两个网站:
- 该测试工具可处理两种上下文中的正则表达式,即
map{}块和HTTPlocation{}块。下面将简要介绍正则表达式在这两种情况下的工作方式。本文不讨论NGINX如何处理所有上下文中的正则表达式;请参阅相关文档:- 运行状况检查:
location{}块,参见nginx.org和NGINX Plus 管理指南map{}块,nginx.org- URI重写:nginx.org和NGINX Plus 管理指南
- 虚拟服务器名称:nginx.org和NGINX Plus 管理指南
- 此测试工具特意采用尽可能简单的设计,且仅用于一个目的:使用实际的NGINX正则表达式引擎,按用户编写的内容测试用于map和HTTP location的正则表达式。因此,只需提供少量必要信息,即可创建可用的NGINX配置。我们暂无添加其他功能(例如在测试前验证正则表达式)的计划,因为这会违背简单易用的设计原则。当然,我们会积极修复错误;请在我们的Issues选项卡中提交问题:GitHub仓库。
概述
在详细介绍正则表达式测试工具之前,我们先来讨论如何在NGINX的location和map中使用正则表达式。
位置
NGINX location{} 块中的正则表达式采用以下形式:
location regex {
#...
}例如,使用以下正则表达式的location{}块可处理URI以myapp/filename.php结尾的所有PHP请求,例如/test/myapp/hello.php和/myapp/hello.php。波浪号后的星号(~*)使匹配不区分大小写。
location ~* /myapp/.+\.php$ {
#...
}NGINX和正则表达式测试工具支持在位置捕获组,用于location{}块中。在以下示例中,第一个组捕获PHP文件名之前的所有内容,第二个组捕获PHP文件名:
location ~* (.*/myapp)/(.+\.php)$ {
#...
}对于URI /myapp/hello.php,变量$1设置为/myapp,$2设置为hello.php。
NGINX还支持命名捕获组:
location ~* (?<begin>.*myapp)/(?<end>.+\.php)$ {
#...
}在这种情况下,变量$begin设置为/myapp,$end设置为hello.php。
正则表达式测试工具支持命名捕获组,但在输出中会将其视为位置捕获组,显示其序号而非名称。
映射
使用正则表达式的NGINX map{}块采用以下形式:
map variable-to-test variable-to-set {
regex1 value-to-set-if-match;
regex2 value-to-set-if-match;
#...
regexN value-to-set-if-match;
default value-to-set-if-no-match;
}例如,此map{}块会将变量$isphp设置为1,条件是URI(记录在变量$uri中)以.php结尾;否则设置为0(匹配区分大小写):
map $uri $isphp {
~\.php$ 1;
default 0;
}对于映射,NGINX和正则表达式测试工具均支持位置捕获组和命名捕获组。
例如,以下两个映射都将变量$fileext设置为文件扩展名的值。在本例中,该值也会被捕获为$1:
map $uri $fileext {
~*.+\.(.+)$ $1;
default '';
}在此示例中为“$ext”:
map $uri $fileext {
~*.+\.(?<ext>.+)$ $ext;
default '';
}正则表达式测试器可用于map{}块,适用于http{}和stream{}上下文,因为映射在这两种上下文中的语法和行为相同。但请注意,如果映射位于stream{}上下文中,则只能使用测试器输出的map{}块。有关详细信息,请参阅下方注释。
正则表达式测试工具
正则表达式测试器在安装了NGINX和NGINX Unit的Docker容器中实现。NGINX Unit提供两种版本的PHP页面,一种用于location{}块中的正则表达式,另一种用于map{}块中的正则表达式。这两个页面会提示用户输入不同的内容:
- Location页面:
- 正则表达式
- 区分大小写
- URI
- 映射页面:
- 正则表达式
- 区分大小写
- 要测试的值(作为
map指令第一个参数的变量值) - 要设置到第二个参数所指定变量中的值,该参数属于
map指令
提供相关信息后,点击“测试”按钮。测试工具会生成所需的NGINX配置文件,重新加载配置,并发送请求以测试正则表达式。随后将显示结果,并说明是否找到匹配项。如果找到匹配项,“位置测试工具”页面将显示捕获组的值,“映射测试工具”页面将显示映射所设置的值。
Location页面示例
此示例显示了对正则表达式(.*myapp)/(.+\.php)$与URI/myapp/hello.php进行不区分大小写匹配测试的结果:

地图页面示例
此示例显示了对正则表达式 .+\.(?<ext>.*)$ 与值 /myapp/hello.php 进行不区分大小写匹配的结果,并将命名捕获组 $ext 用作要设置的值:

注意:如果映射位于stream{}上下文中,则配置只能使用输出中的map{}块。server{}块无效,因为其中包含location{}块,而stream{}上下文不支持该块。
总结
可以看到,NGINX配置非常简短。主要工作由PHP页面完成:该页面根据用户输入的值生成所需的NGINX配置文件,重新加载NGINX,向NGINX发送请求并显示结果。
您可以亲自试用正则表达式测试工具:所有代码均可在我们的GitHub代码仓库(https://github.com/nginxinc/NGINX-Demos/tree/master/nginx-regex-tester)中获取。
为便于快速启动并运行正则表达式测试工具,已包含所有必要文件。要构建Docker镜像和容器,只需运行:
$ docker-compose up -d然后在浏览器中访问http://Docker-host/regextester.php。
希望tester能帮助您使用正则表达式,并让您初步了解NGINX的强大功能、灵活性和简洁性。
要使用NGINX Plus试用正则表达式测试工具,立即开始30天免费试用,或联系我们,讨论您的用例。
关于作者

相关博客文章
NGINX Plus R26 正式发布
NGINX Plus R26通过缓存JSON Web密钥集加快JWT验证,并强化TLS握手,从而提升安全性。NGINX JavaScript的新功能包括增强对异步函数的支持,以及实现WebCrypto API。
使用NGINX App Protect DoS保护gRPC应用,抵御严重的DoS攻击
gRPC具备开发人员设计和部署现代应用所需的速度与灵活性,但其开放性也使其极易受到第7层DoS攻击。NGINX App Protect DoS可保护gRPC应用免受此类破坏性攻击。
Ingress Controller 选型指南(第 2 部分):风险与面向未来的规划
了解选择错误的Ingress控制器可能带来的风险,以及如何从关键方面着手,让您的选择更好地适应未来需求。
NGINX Plus R19 正式发布
NGINX Plus R19扩展了监控功能,不仅提供更多指标,还新增了指标分析方式;增加试运行模式,用于测试限速效果;增强键值存储,以支持IP地址范围;并使限速更加动态。
NGINX现已正式加入F5
NGINX现已正式成为F5的一部分。Gus Robertson现任F5 NGINX业务部门负责人。他阐述了两家公司在人才、文化和愿景方面融合的价值,以及双方将如何携手增强NGINX的开源产品和商业产品。
