I want an nginx location directive that would match all urls with "xyz" and not match ".php"
I tried this
location ~* /(.*)xyz/(.*开发者_Go百科)(?!\.php)(.*)$ {}
but for example it always seem to match both /xyz/1 and /xyz/1.php but it should have matched only /xyz/1
You should be more specific about the begin and end of the location. If .php
should not appear at the end of the location, put $
in the look-ahead assertion:
location ~* /(.*)xyz/(.*)(?!.*\.php$)(.*)$ {}
And if xyz
should be a proper path segment and the first path segment (so it must start with /xyz/
), use this:
location ~* ^/xyz/(?!.*\.php$)(.*)$ {}
I don't think you can do this without a separate regex checking to make sure that ".php" is absent. The problem is that constructs like .*
will swallow up enough characters to make sure that your negative lookahead never applies.
Well, as Michael said, though .*? (note the '?') will make the search non-greedy and it could work.
...Or, you could try (rather hackish):
[^.][^p][^h][^p]
Might works, might not... It definately is sort of a hack.
This one is simple, yet it can be tough to see. The second (.*) in the regex is "greedy", hence, it will capture everything including the ".php" so, to the parser's "eyes" there is no ".php" after it (it's already passed) and the result is a match. :(
Just make the second .* lazy by changing it to .*? and it will solve your problem :
location ~* /(.*)xyz/(.*?)(?!\.php)(.*)$ {}
I suggest you read this article, it explains it in a much better way than I. :D
Thanks all, we finally came up with this
location ~* ^/xyz([^.]*)/([^.]*)$ {
rewrite ^/xyz([^.]*)/([^.]*)$ /xyz$1/index.php/$2 last;
}
and it works.
精彩评论