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

在研究与 NGINX 一起使用的正则表达式 (regex) 时,我想到了一种在实际 NGINX 配置中轻松测试正则表达式的方法。 (正则表达式测试器对于 NGINX Open Source 和 NGINX Plus 的工作原理是一样的,为了便于阅读,我将在本文中简单地提及 NGINX。)

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

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

注释:

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

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

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

    • 健康检查:

      • HTTP – nginx.org 和 NGINX Plus 管理指南
      • TCP – nginx.org 和 NGINX Plus 管理指南
      • UDP – nginx.org 和 NGINX Plus 管理指南
    • 位置{}块 – nginx.org 和 NGINX Plus 管理指南
    • 映射{}块 – nginx.org
    • URI 重写 – nginx.org 和 NGINX Plus 管理指南
    • 虚拟服务器名称 – nginx.org 和 NGINX Plus 管理指南
  • 测试程序有意设计得尽可能简单,并实现一个目的:使用实际的 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 还支持命名捕获组:

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

在本例中,变量 $begin 设置为 /myapp,$end 设置为 hello.php。

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

地图

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

将变量映射到测试变量到集合 {
regex1 匹配时设置的值;
regex2 匹配时设置的值;
#…
regexN 匹配时设置的值;
如果不匹配则设置默认值;
}

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

地图 $uri $isphp {
〜\.php$ 1;
默认 0;
}

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

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

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

本例中的 $ext 为:

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

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

正则表达式测试器

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

  • 位置页面:

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

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

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

位置页面示例

此示例显示了针对 URI /myapp/hello.php 的正则表达式 (.*myapp)/(.+\.php)$ 不区分大小写的测试结果:

 

地图页面示例

此示例显示了正则表达式 .+\.(?.*)$ 对值 /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。

我希望测试仪在使用正则表达式时对您有所帮助,并且它可以让您了解 NGINX 的一些强大功能、灵活性和简单性。

要使用 NGINX Plus 试用正则表达式测试器,请立即开始 30 天免费试用,或联系我们讨论您的使用案例。


评论

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注