nginx正则表达式
1、nginx配置基础
1、正则表达式匹配
~ 区分⼤⼩写匹配
~* 不区分⼤⼩写匹配
!~和!~*分别为区分⼤⼩写不匹配及不区分⼤⼩写不匹配
^ 以什么开头的匹配
$ 以什么结尾的匹配
转义字符。可以转. * ?等
* 代表任意字符
2、⽂件及⽬录匹配
-
f和!-f⽤来判断是否存在⽂件
-d和!-d⽤来判断是否存在⽬录
-e和!-e⽤来判断是否存在⽂件或⽬录
-x和!-x⽤来判断⽂件是否可执⾏
例:
location = /
#匹配任何查询,因为所有请求都已 / 开头。但是正则表达式规则和长的块规则将被优先和查询匹配
location ^~ /images/ {
nginx 配置文件
# 匹配任何已/images/开头的任何查询并且停⽌搜索。任何正则表达式将不会被测试。
location ~* .(gif|jpg|jpeg)$ {
# 匹配任何已.gif、.jpg 或 .jpeg 结尾的请求
⼊门
1、if指令
所有的Nginx内置变量都可以通过if指令和正则表达式来进⾏匹配,并且根据匹配结果进⾏⼀些操作,如下:
代码如下复制代码
if ($http_user_agent ~ MSIE) {
rewrite  ^(.*)$  /msie/$1  break;
}
if ($http_cookie ~* "id=([^;] +)(?:;|$)" ) {
set  $id  $1;
}
使⽤符号~*和~模式匹配的正则表达式:
1.~为区分⼤⼩写的匹配。
2.~*不区分⼤⼩写的匹配(匹配firefox的正则同时匹配FireFox)。
3.!~和!~*意为“不匹配的”。
Nginx在很多模块中都有内置的变量,常⽤的内置变量在HTTP核⼼模块中,这些变量都可以使⽤正则表达式进⾏匹配。
2、可以通过正则表达式匹配的指令
location
查看维基:location
可能这个指令是我们平时使⽤正则匹配⽤的最多的指令:
代码如下复制代码
location ~ .*.php?$ {
location ~ .*.php?$ {
fastcgi_pass  127.0.0.1:9000;
fastcgi_index  index.php;
fastcgi_param  SCRIPT_FILENAME
/data/wwwsite/test/$fastcgi_script_name;
include        f;
}
⼏乎每个基于LEMP的主机都会有如上⼀段代码。他的匹配规则类似于if指令,不过他多了三个标识符,^~、=、@。并
且它没有取反运算符!,这三个标识符的作⽤分别是:
1.^~ 标识符后⾯跟⼀个字符串。Nginx将在这个字符串匹配后停⽌进⾏正则表达式的匹配(location指令中正则表达
式的匹配的结果优先使⽤),如:location ^~ /images/,你希望对/images/这个⽬录进⾏⼀些特别的操
作,如增加
expires头,防盗链等,但是你⼜想把除了这个⽬录的图⽚外的所有图⽚只进⾏增加expires头的操作,这个操作可能
会⽤到另外⼀个location,例如:location ~* .(gif|jpg|jpeg)$,这样,如果有请求/images/1.jpg,nginx如何决
定去进⾏哪个location中的操作呢?结果取决于标识符^~,如果你这样写:location /images/,这样nginx会将1.jpg
匹配到location ~* .(gif|jpg|jpeg)$这个location中,这并不是你需要的结果,⽽增加了^~这个标识符后,它在匹
配了/images/这个字符串后就停⽌搜索其它带正则的location。
2.= 表⽰精确的查地址,如location = /它只会匹配uri为/的请求,如果请求为/index.html,将查另外的
location,⽽不会匹配这个,当然可以写两个location,location = /和location /,这样/index.html将匹配到后者
,如果你的站点对/的请求量较⼤,可以使⽤这个⽅法来加快请求的响应速度。
3.@ 表⽰为⼀个location进⾏命名,即⾃定义⼀个location,这个location不能被外界所访问,只能⽤于Nginx产⽣的
⼦请求,主要为error_page和try_files。
注意,这3个标识符后⾯不能跟正则表达式,虽然配置⽂件检查会通过,⽽且没有任何警告,但是他们并不会进⾏匹配
综上所述,location指令对于后⾯值的匹配顺序为:
1.标识符“=”的location会最先进⾏匹配,如果请求uri匹配这个location,将对请求使⽤这个location的配置。
2.进⾏字符串匹配,如果匹配到的location有^~这个标识符,匹配停⽌返回这个location的配置。
3.按照配置⽂件中定义的顺序进⾏正则表达式匹配。最早匹配的location将返回⾥⾯的配置。
4.如果正则表达式能够匹配到请求的uri,将使⽤这个正则对应的location,如果没有,则使⽤第⼆条匹配的结果。
server_name
查看维基:server_name
server_name⽤于配置基于域名或IP的虚拟主机,这个指令也是可以使⽤正则表达式的,但是注意,这个指令中的正则
表达式不⽤带任何的标识符,但是必须以~开头:
代码如下复制代码
server {
server_name  ample  ~^wwwd+.example$;
}
server_name指令中的正则表达式可以使⽤引⽤,⾼级的应⽤可以查看这篇⽂章:在server_name中使
⽤正则表达式
fastcgi_split_path_info
查看维基:fastcgi_split_path_info
这个指令按照CGI标准来设置SCRIPT_FILENAME (SCRIPT_NAME)和PATH_INFO变量,它是⼀个被分割成两部分(两个引⽤)的正则表达式。如下:
代码如下复制代码
location ~ ^.+.php {
(...)
fastcgi_split_path_info ^(.+.php)(.*)$;
fastcgi_param SCRIPT_FILENAME /path/to/php$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
(...)
}
第⼀个引⽤(.+.php)加上/path/to/php将作为SCRIPT_FILENAME,第⼆个引⽤(.*)为PATH_INFO,例如请求的完整URI为show.php/article/0001,则上例中SCRIPT_FILENAME的值为/path/to/php/show.php,PATH_INFO则
为/article/0001。
这个指令通常⽤于⼀些通过PATH_INFO美化URI的框架(例如CodeIgniter)。
gzip_disable
查看维基:gzip_disable
通过正则表达式来指定在哪些浏览器中禁⽤gzip压缩。
gzip_disable    "msie6";rewrite
查看维基:rewrite
这个指令应该也是⽤的⽐较多的,它需要使⽤完整的包含引⽤的正则表达式:
代码如下复制代码
rewrite  "/photos/([0-9] {2})([0-9] {2})([0-9] {2})" /path/to/photos/$1/$1$2/$1$2$3.png;通常
环境下我们
会把它和if结合来使⽤:
代码如下复制代码
if ($host ~* www.(.*)) {
set $host_without_www $1;
rewrite ^(.*)$ $host_without_www$1 permanent; # $1为'/foo',⽽不
是'domain/foo'
}
Nginx中的正则如何匹配中⽂
⾸先确定在编译pcre时加了enable-utf8参数,如果没有,请重新编译pcre,然后就可以在Nginx的配置⽂件中使⽤这样的正则:”(*UTF8)^/[x{4e00}-x{9fbf}]+)$”注意引号和前⾯的(*UTF8),(*UTF8)将告诉这个正则切换为UTF8模
式。
代码如下复制代码
[root@backup conf]# pcretest
PCRE version 8.10 2010-06-25
re> /^[x{4e00}-x{9fbf}]+/8
data> 测试
0: x{6d4b}x{8bd5}
data> Nginx模块参考⼿册中⽂版
No match
data> 参考⼿册中⽂版
0: x{53c2}x{8003}x{624b}x{518c}x{4e2d}x{6587}x{7248}
location顺序错误导致下载.php源码⽽不执⾏php程序的问题
看下⾯的例⼦⽚断(server段、wordpress安装到多个⽬录):
=====================================
代码如下复制代码
location / {
try_files $uri $uri/ /index.html;
}
location /user1/ {
try_files $uri $uri/ /user1/index.php?q=$uri&$args;
}
location ~* ^/(user2|user3)/ {
try_files $uri $uri/ /$1/index.php?q=$uri&$args;
}
location ~ .php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi_params;
}
=====================================
访问 /user1/会正常执⾏php程序。
访问 /user2/ 或 /user3/ 都不会执⾏程序,⽽是直接下载程序的源代码。
原因在哪⾥?看到他们地区别了吗?
/user1/是普通location写法
⽽/user2/ 或 /user3/ 是正则表达式匹配的location
问题就出在了/user2/ 或 /user3/匹配location指令使⽤了正则表达式,所以必须注意代码段的先后顺序,必须把location ~ .php$ {...}段上移、放到它的前⾯去。
正确的代码举例:
=====================================
代码如下复制代码
location / {
try_files $uri $uri/ /index.html;
}
location /user1/ {
try_files $uri $uri/ /user1/index.php?q=$uri&$args;
}
location ~ .php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi_params;
}
location ~* ^/(user2|user3)/ {
try_files $uri $uri/ /$1/index.php?q=$uri&$args;
}
=====================================
【注意】对于普通location指令⾏,是没有任何顺序的要求的。如果你也遇到了类似的问题,可以尝试调整使⽤正则表达式的location指令⽚断的顺序来调试

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。