在两个表达式的第三行中,^
和^.*$
之间有什么区别。它们彼此相同还是不同
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} (.+)/$
RewriteRule ^ %1 [L,R=301]
和
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} (.+)/$
RewriteRule ^.*$ %1 [L,R=301]
这两个例子的最终结果是相同的,但它们在技术上不同,^
在这种情况下更有效。
在这两个规则中,您只需要RewriteRule
指令就可以成功执行所有操作,而两个regex都可以实现这一点。
^
-这个正则表达式只是断言字符串锚的开始,所以它对所有内容都是成功的,但不匹配任何内容。($0
反向引用为空。(
更新:例如,给定/abc
的请求,那么大约涉及的步骤是:
^
断言URL路径的开始- 正则表达式中没有更多符号。正则表达式成功。请求的URL路径中没有任何匹配项。
$0
反向引用为空完成
^.*$
-此正则表达式匹配所有内容,因此它对所有都是成功的,并匹配所有。由于它实际上匹配所有,$0
backreference存储匹配的整个URL路径。如果你只是需要成功,那么这会降低效率,因为它会遍历整个URL路径。顺便说一句,这与简单的.*
相同,因为regex默认情况下是贪婪。
更新:例如,给定一个/abc
请求,那么大约涉及的步骤是:
^
断言URL路径的开始- CCD_ 15与CCD_ 17中的CCD_
*
量词重复先前匹配0次或更多次(贪婪(- CCD_ 19与CCD_ 21中的CCD_
- CCD_ 22量词重复先前的匹配0次或更多次(贪婪(
- CCD_ 23与CCD_ 25中的CCD_
- CCD_ 26量词重复先前的匹配0次或更多次(贪婪(
.
与任何内容都不匹配(失败(,因为我们已经到达URL路径的末尾- CCD_ 28断言URL路径的末尾
- 正则表达式中没有更多符号。正则表达式成功。已通过遍历URL路径来匹配整个URL路径。
$0
反向引用包含整个URL路径完成
但是。。。
RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_URI} (.+)/$ RewriteRule ^ %1 [L,R=301]
由于不需要第二个RewriteCond
指令,这实际上可以提高效率。这种检查应该在RewriteRule
模式中进行,以避免对每个请求进行文件系统检查,而不仅仅是以斜杠结尾的请求(这是所需的全部内容(。例如:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.+)/$ /$1 [L,R=301]
首先处理RewriteRule
模式,然后再处理任何条件,因此您应该在这里进行尽可能多的处理。请注意在替换字符串上添加了斜线前缀,$1
反向引用中缺少该前缀。(斜杠是%1
反向引用的一部分,正如您之前使用的那样,因为REQUEST_URI
服务器变量以斜杠开头。(