博客 | NGINX

NGINX 和 NGINX Plus 的正则表达式测试器

NGINX-F5-horiz-black-type-RGB 的一部分
里克·尼尔森缩略图
里克·尼尔森
2019 年 6 月 11 日发布

在研究用于 NGINX 的正则表达式 (regex) 时,我想到了一种可以从实际 NGINX 配置中轻松测试正则表达式的方法。 (正则表达式测试器对于NGINX Open SourceNGINX Plus 的工作方式相同,为了方便阅读,我将在本文中简称为NGINX 。)

对正则表达式的支持是 NGINX 的强大功能之一,但正则表达式可能很复杂且难以正确使用,特别是如果您不经常使用它们的话。 NGINX 允许在配置的多个部分使用正则表达式,例如位置、地图、重写和服务器名称。 此处描述的测试器适用于位置和地图中的正则表达式。

还有其他免费的在线正则表达式测试器适用于大多数正则表达式,但 NGINX 使用了一些针对 Web应用优化的非标准快捷方式。 例如,您不必像在标准正则表达式中那样转义 URI 中的正斜杠 (/)。 此外,当在地图中使用正则表达式时,您可以根据匹配指定要设置的值。 对于其他正则表达式测试器,您可能必须修改正则表达式,或者在映射的情况下推断将设置什么值。 此外,能够在实际环境中使用实际正则表达式引擎测试正则表达式总是好的。

笔记:

  • NGINX 使用Perl 兼容正则表达式(PCRE),本文假设您对 NGINX 和正则表达式有基本的了解。 解释如何构建正则表达式超出了这篇文章的范围,并且我们很遗憾无法在评论部分回答有关如何构建正则表达式的进一步问题。

    有许多网站提供用于构建正则表达式的工具或文档。 我们发现两个有用的方法是:

  • 测试人员在两种情况下处理正则表达式 - map{}块和 HTTP location{}块 - 下面简要讨论了正则表达式在每种情况下的工作方式。 解释 NGINX 如何在所有上下文中处理正则表达式超出了本文的范围;请参阅我们的文档:

  • 测试器被有意设计得尽可能简单,并且只实现一个目的:测试用户编写的正则表达式,使用实际的 NGINX 正则表达式引擎来获取地图和 HTTP 位置。 因此,您只需提供少量信息即可创建有效的 NGINX 配置。我们没有计划添加功能(例如在测试之前验证正则表达式),因为这会违反简单性的指导原则。 当然,我们很乐意修复错误;请在我们的GitHub 存储库“问题”选项卡上提交它们。

概述

在我们深入了解正则表达式测试器的细节之前,让我们首先讨论如何在 NGINX 位置和映射中使用正则表达式。

位置

NGINX location{}块中的正则表达式的形式为:

位置正则表达式{ #... }

例如,具有以下正则表达式的location{}块将处理所有 URI 以myapp/ filename.php结尾的 PHP 请求,例如/test/myapp/hello.php/myapp/hello.php 。 波浪号 ( ~* ) 后的星号使匹配不区分大小写。

位置 ~* /myapp/.+\.php$ {
#...
}

NGINX 和正则表达式测试器支持location{}块中的位置捕获组。 在以下示例中,第一组捕获 PHP 文件名之前的所有内容,第二组捕获 PHP 文件名:

位置 ~* (.*/myapp)/(.+\.php)$ {
#...
}

对于 URI /myapp/hello.php ,变量$1设置为/myapp$2设置为hello.php

NGINX 还支持命名捕获组:

位置 ~* (?<begin>.*myapp)/(?<end>.+\.php)$ {
#...
}

在这种情况下,变量$begin设置为/myapp$end设置为hello.php

正则表达式测试器支持命名捕获组,但在输出中将它们视为位置捕获组,显示它们的序数而不是名称。

地图

使用正则表达式的 NGINX map{}块的形式为:

映射要测试的变量以设置变量{ regex1 如果匹配则要设置的值; regex2 如果匹配则要设置的值; #... regexN 如果匹配则要设置的值; 如果不匹配则默认要设置的值; }

例如,此map{}块将变量$isphp设置为1如果 URI(记录在$uri变量中)以.php结尾,并且0如果没有(匹配区分大小写):

映射 $uri $isphp {
~\.php$ 1;
默认 0;
}

对于地图,NGINX 和正则表达式测试器支持位置和命名捕获组。

例如,以下映射都将变量$fileext设置为文件扩展名的值,在此示例中也被捕获为$1

映射 $uri $fileext {
    〜*.+\.(.+)$ $1;
    默认      '';
}

在本例中为$ext

映射 $uri $fileext {
~*.+\.(?<ext>.+)$ $ext;
默认 '';
}

您可以在http{}stream{}上下文中对map{}块使用正则表达式测试器,因为在这两个上下文中,映射的语法和行为是相同的。 但请注意,如果您的地图位于stream{}上下文中,则您只能使用来自测试程序输出的map{}块。 请参阅下面的注释以了解详细信息。

正则表达式测试器

正则表达式测试器是在安装了 NGINX 和NGINX Unit 的Docker 容器中实现的。 NGINX Unit 提供两种 PHP 页面变体,一种用于location{}块中的正则表达式,另一种用于map{}块中的正则表达式。 这两个页面提示用户输入不同的内容:

  • 位置页面:

    • 正则表达式
    • 区分大小写
    • URI
  • 地图页面:

    • 正则表达式
    • 区分大小写
    • 要测试的值(作为map指令的第一个参数的变量的值)
    • map指令的第二个参数指定的变量中设置的值

提供信息后,单击测试按钮。 测试人员生成必要的 NGINX 配置文件,重新加载配置,并发送请求来测试正则表达式。 然后显示结果并指示是否找到匹配项。 如果是,则在位置测试器页面上显示捕获组的值,并在地图测试器页面上报告地图设置的值。

位置页面示例

此示例显示对 URI /myapp/hello.php进行正则表达式(.*myapp)/(.+\.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 天免费试用联系我们讨论您的用例


“这篇博文可能引用了不再可用和/或不再支持的产品。 有关 F5 NGINX 产品和解决方案的最新信息,请探索我们的NGINX 产品系列。 NGINX 现在是 F5 的一部分。 所有之前的 NGINX.com 链接都将重定向至 F5.com 上的类似 NGINX 内容。”