简体   繁体   中英

difference between ^ vs ^.*$ in Rewrite rule apache in htaccess

What is the difference between ^ vs ^.*$ in the third line of both the expressions. Are they same or different from each other

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} (.+)/$
RewriteRule ^  %1 [L,R=301]

and

 RewriteCond %{REQUEST_FILENAME} !-d
 RewriteCond %{REQUEST_URI} (.+)/$
 RewriteRule ^.*$  %1 [L,R=301]

The net result in these two examples is the same, but they are technically different and ^ is more efficient in this case.

In both of these rules you simply need the RewriteRule directive to be successful for everything and both regex achieve that.

^ - This regex simply asserts the start-of-string anchor, so it is successful for everything, but matches nothing. (The $0 backreference is empty.)

UPDATE: For example, given a request for /abc , then the approx steps involved are:

  1. ^ asserts the start of the URL-path.
  2. No more symbols in the regex. The regex is successful. Nothing has been matched in the requested URL-path. The $0 backreference is empty. DONE

^.*$ - This regex matches anything and everything, so it is successful for everything and matches everything . Since it actually matches everything , the $0 backreference stores the entire URL-path that is matched. If you simply need to be successful then this is less efficient as it traverses the entire URL-path. Incidentally, this is the same as simply .* because regex is greedy by default.

UPDATE: For example, given a request for /abc , then the approx steps involved are:

  1. ^ asserts the start of the URL-path.
  2. . matches a in abc .
  3. * quantifier repeats the previous match 0 or more times (greedy).
  4. . matches b in abc .
  5. * quantifier repeats the previous match 0 or more times (greedy).
  6. . matches c in abc .
  7. * quantifier repeats the previous match 0 or more times (greedy).
  8. . does not match anything (fails) since we have reached the end of the URL-path.
  9. $ asserts the end of the URL-path.
  10. No more symbols in the regex. The regex is successful. The entire URL-path has been matched by traversing through the URL-path. The $0 backreference contains the entire URL-path. DONE

However...

 RewriteCond %{REQUEST_FILENAME}.-d RewriteCond %{REQUEST_URI} (,+)/$ RewriteRule ^ %1 [L,R=301]

This could actually be made more efficient since the 2nd RewriteCond directive is not required. This check should be made in the RewriteRule pattern instead, to avoid a filesystem check on every request, not just requests that end in a slash (which is all that's required). For example:

RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.+)/$ /$1 [L,R=301]

The RewriteRule pattern is processed first, before any of the conditions, so you should do as much processing here as possible. Note the addition of the slash prefix on the substitution string, which is missing from the $1 backreference. (The slash is otherwise part of the %1 backreference - as you used previously - because the REQUEST_URI server variable starts with a slash.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM