学过java正则表达式的同学或许看起来有点熟悉,确实是跟nginx正则表达式有一些相同的地方。 为了更轻松地从java表达式向掌握nginx正则表达式过度,现在来看一下它们的差别在哪里。
~ 区分大小写(大小写敏感)匹配成功 ~* 不区分大小写匹配成功
加上 ! 号则表示逆命题
!~ 区分大小写匹配失败 !~* 不区分大小写匹配失败
而在java正则表达式中,是这样设定对大小写敏感的
(?i)abc abc三个字母都忽略大小写 a(?i)bc 只是bc忽略大小写 a((?i)b)c 只有b忽略大小写
看得出,(?!)起到忽略大小写的作用,作用域范围为在它后面的字符,或者位于()括号内的整体。
*
nginx正则表达式中, * 表示匹配任何字符,可以为空,长度不限。 而在Java正则中,* 表示零次或多次匹配前面的字符或子表达式。例如,zo* 匹配”z”和”zoo”。* 等效于 {0,}。
代码中,则可以用Pattern.compile(rexp,Pattern.CASE_INSENSITIVE)表示整体rexp表达式都忽略大小写
^ 和 $
这两个java跟nginx都一样,都是:
^ 以什么开头的匹配 $ 以什么结尾的匹配 例如:
location ^~ /images/ { }匹配任何已/images/开头的任何查询并且成功匹配这几个字符后,停止后续字符的匹配。
location ~* .(gif|jpg|jpeg)$ { }
匹配任何已.gif、.jpg 或 .jpeg 结尾的请求
=
nginx中表示精确的查找地址,(类似于是否优先匹配) 标识符 = 的location会最先进行匹配,如果请求URL完全匹配这个location,即代表成功匹配。
如location = / 它只会匹配URL为/的请求,如果请求为/index.html,不会匹配这个。反之,将去匹配另外的location的正则表达式,匹配 location /index.html,location ~ /*.html等。 当然可以写两个location,location = /和location /,这样/index.html将匹配到后者,如果站点对/的请求量较大,可以使用这个方法来加快请求的响应速度。
而java中,= 就是匹配 =号,没有像nginx的这种用法和概念,反之java中是用? 来表示贪心还是不贪心的策略。
当?字符紧随任何其他限定符(*、+、?、{n}、{n,}、{n,m})之后时,匹配模式是”非贪心的”。”非贪心的”模式匹配搜索到的、尽可能短的字符串,而默认的”贪心的”模式匹配搜索到的、尽可能长的字符串。 例如,在字符串”oooo”中,”o+?”只匹配单个”o”,而”o+”匹配所有”o”。
.
Nginx中, . 这个概念跟java中的 . 一样,表示匹配任意一个字符。 而 . 就是匹配 . 字符。
在nginx正则表达式中,还有一个很重要的概念。匹配文件或者文件目录,如:
-f和!-f用来判断是否存在文件 -d和!-d用来判断是否存在目录 -e和!-e用来判断是否存在文件或目录 -x和!-x用来判断文件是否可执行
例如,文件和目录不存在的时候重定向:
if (!-e $request_filename) { proxy_pass http://127.0.0.1; }
最后,结合看一些综合的例子吧
禁止访问多个目录 location ~ ^/(cron|templates)/ { deny all; break; }
禁止访问以/data开头的文件 location ~ ^/data { deny all; }
禁止访问以.sh,.flv,.mp3为文件后缀名的文件 location ~ .*.(sh|flv|mp3)$ { return 403; }
设置某些类型文件的浏览器缓存时间 location ~ .*.(gif|jpg|jpeg|png|bmp|swf) expires30d;location .∗.(js|css) { expires 1h; }