问题
I have URLs in a scheme
/([0-9]*)/some/path/script.jsf?someId=([0-9]*)
and I'd like to redirect to $2 the user if $1 doesn't match $2. So for example if the user requests
/1/some/path/script.jsf?someId=1
everthing is fine and the user shouldn't be redirected but if the user requests
/1/some/path/script.jsf?someId=2
the user should be redirected to
/2/some/path/script.jsf?someId=2
I've tried this rule:
RewriteCond %{REQUEST_URI} ^/([0-9]*)/
RewriteCond %{QUERY_STRING} someId=([0-9]*)
RewriteCond %1 !%2
RewriteRule (.*) /%2/some/path/script.jsf?someId=%2 [R]
but %2 seems always empty. So I've tried this rule:
RewriteCond %{REQUEST_URI} ^/([0-9]*)/some/path/script.jsf?someId=([0-9]*)
RewriteCond %1 !%2
RewriteRule (.*) /%2/)/some/path/script.jsf?someId=%2 [R]
回答1:
%n
only accesses backreferences from
the last matched
RewriteCond
in the current set of conditions.
That's why your %2
always seems empty in your first set of rules.
Your second attempt gets around this problem for the RewriteCond %1 !%2
, but you can't refer to %2
in your RewriteRule
, as it refers to, again, the last matched RewriteCond
.
If you're running Apache 2, there's a very simple way to do this using a negative lookahead assertion:
RewriteRule ^/([0-9]*)/some/path/script.jsf?someId=(?!$1(?:$|[^0-9]))([0-9]*) /$2/some/path/script.jsf?someId=$2 [R]
The important part is
(?!$1(?:$|[^0-9]))
which asserts that the next sequence of characters cannot be exactly the number in $1
. (The $|[^0-9]
bit assures that trailing numbers are considered.)
来源:https://stackoverflow.com/questions/13289007/compare-and-rewrite-url-with-mod-rewrite-based-on-path-and-query-string