PCRE 图书馆
Nginx 使用PCRE文库用C写的。
有一个巨大的man page,有时有点难以理解,但很详细。
其中,您会发现前瞻/后顾功能,就像在 Perl 中一样。
积极/消极的向前/向后展望
如果字符串的一部分后面/前面没有表达式,则正向/负向前视/后视允许匹配字符串。后视表达式仅限于固定字符串,因为大多数实现不可能向后应用正则表达式,因为您需要知道为此返回了多少步。向前看显然不会受到这种限制,因此您可以像平常一样使用正则表达式。
这是手册页的相关部分:
前瞻和后瞻断言
(?=...) positive look ahead
(?!...) negative look ahead
(?<=...) positive look behind
(?<!...) negative look behind
Each top-level branch of a look behind must be of a fixed length.
不幸的是,您无法通过前瞻捕获字符串的结尾。
行动中回头看
因此,我们的第一次尝试将是从字符串末尾使用负向查找:
location ~ .+(?<!\.php)$ {
...
}
这意味着“仅捕获不以.php
“。这与我们已经需要的非常接近。但是还需要添加更多内容才能使其按预期工作。
嵌套位置
事实上,没有任何东西可以保证此时您将拥有一个包含文件扩展名的字符串。更可能是anything except ^.+\.php$
。为了确保这是一个真实的文件后缀,彻底改变此限制的自然方法是使用嵌套位置块,其中最受限制的部分是顶点。所以我们的配置现在如下所示。
location ~ .+(?<!\.php)$ {
location ~ ^[^.]+\.[^.]+$ {
try_files $uri /images/default.gif;
}
}
就是这样!
你的第二期
以下是我在针对您面临的第二个问题(其他 URL 上的 404 错误)进行帖子更新后的评论。
As ~ .+(?<!\.php)$
匹配所有内容,除了\.php$
并且位置是嵌套的,需要嵌套位置块/
并将其转换为正则表达式匹配:
location ~ .+(?<!\.php)$ {
location ~ ^[^.]+\.[^.]+$ {
try_files $uri /images/default.gif;
}
location ~ / {
# your stuff
}
}
另请注意,您可能会陷入无限循环try_files $uri /images/default.gif;
部分因为最后一个参数try_files
指令是一个内部重定向或 HTTP 代码。因此,如果/images/default.gif
不解析为文件,请求将再经过此位置块 10 次,直到 nginx 停止处理并返回 HTTP 500。因此将其更改为try_files $uri /images/default.gif =404;
.