为什么要RewriteRule。和^(。*)$一样工作吗?

时间:2012-09-30 01:40:03

标签: regex apache mod-rewrite pcre

请考虑以下事项:

RewriteRule ^(.*)$ index.php/$1

根据我对mod_rewrite的初步知识知识,这应该与example.com/?query=string之间的整个网址部分匹配,然后将其添加到index.php/之前,通常,这正是会发生什么。

http://example.com/some/stuff -> http://example.com/index.php/some/stuff

现在,考虑一下:

RewriteRule . index.php

根据Concrete5 CMS当前更新的开发人员,这完全相同。事实上,它似乎也在我的服务器上做到了。

我的问题是,为什么第二个RewriteRule会产生相同的结果而不是像

那样的结果
http://example.com/some/stuff -> http://example.com/index.phpome/stuff

.不应匹配一个字符,然后用index.php字符串替换吗?这是在Apache 2.2上。

2 个答案:

答案 0 :(得分:1)

RewriteRule ^(.*)$ index.php/$1将匹配并使用捕获的文本创建一个新路径,其中包含最初请求添加到$1所在的末尾的内容。

RewriteRule . index.php匹配,因为它是一个未固定的正则表达式。之前的正则表达式使用^$来锚定匹配,这意味着模式必须完全匹配,而此模式不匹配,这意味着它将匹配字符串中的任何地方,所以任何字符的字符串都匹配。因为mod_rewrite将每个测试视为运行谓词,所以只要匹配就会应用此规则。

当规则匹配时,替换发生。替换是完整的替换,因此如果您不使用$1之类的反向引用,那么原始模式中的任何内容都将丢失。在这种情况下,新路径将变为index.php

因此,2之间存在细微差别,因为第二个直接转到index.php而不将最初请求的路径添加到结尾。很可能Concrete5 CMS正在使用一个前端控制器,它根据它直接从请求中提取的信息进行调度。由于这不是重定向重写,原始请求将被保留,因此只需使用它:将一些责任从Apache转移到应用程序代码的手中,减少对托管环境的依赖。

答案 1 :(得分:0)

左边的匹配不是替换,只是搜索。您必须使用反向引用来替换/保留特定部分。