RewriteRule贪婪

时间:2010-04-20 11:21:33

标签: regex apache mod-rewrite

我一直在寻找几个小时的答案,很抱歉,如果这被问了很多次,我就错过了。

我基本上想要重写以忽略第一个目录。路径中的第一个dir会有所不同所以我认为我可以使用正则表达式。但我的正则表达式一直匹配文件名:

RewriteRule ^([a-z]+)?/(.+)$ $2 [L]

如果我有一个深度,这是有效的:

http://test.domain.com/one/index.php

我得到root的实际索引页面。这就是我想要的。但如果我要深入一点:

http://test.domain.com/one/two/anotherfile.php

我收到一条消息,说没有找到/anotherfile.php,因为它正在查找根目录。所以看来我的正则表达式并没有在最后一个[a-z]之后停止。我感谢任何帮助。

如果重要的话,这就是Apache2。

2 个答案:

答案 0 :(得分:1)

重写引擎重复所有规则,直到在迭代规则之前和之后URI相同。根据规则RewriteRule ^([a-z]+)?/(.+)$ $2 [L]和输入:http://test.domain.com/one/index.php,这就是正在发生的事情:

  1. 从URI中删除前导斜杠(前缀):one/index.php
  2. 应用规则,URI与^([a-z]+)?/(.+)$
  3. 匹配
  4. URI被重写为/index.php
  5. 内部重定向,新URI(/index.php)与旧URI(/one/index.php)不匹配,并通过重写规则运行
  6. 删除前导斜杠
  7. 规则已应用,URI 匹配^([a-z]+)?/(.+)$
  8. 不会重写URI。新URI(/index.php)在运行重写引擎(/index.php)之前与旧URI相同,重写停止
  9. 生成的URI为/index.php

    但是输入:http://test.domain.com/one/two/anotherfile.php

    1. 从URI中删除前导斜杠(前缀):one/two/anotherfile.php
    2. 应用规则,URI与^([a-z]+)?/(.+)$
    3. 匹配
    4. URI被重写为/two/anotherfile.php
    5. 内部重定向,新URI(/two/anotherfile.php)与旧URI(/one/two/anotherfile.php)不匹配,并通过重写规则运行
    6. 删除了前导斜杠(two/anotherfile.php
    7. 规则已应用,URI与^([a-z]+)?/(.+)$
    8. 匹配
    9. URI被重写为/anotherfile.php
    10. 内部重定向,新URI(/anotherfile.php)与旧URI(/two/anotherfile.php)不匹配,并通过重写规则运行
    11. 删除了前导斜杠(anotherfile.php
    12. 规则已应用,URI 匹配^([a-z]+)?/(.+)$
    13. 不会重写URI。新URI(/anotherfile.php)在运行重写引擎(/anotherfile.php)之前与旧URI相同,重写停止
    14. 生成的URI为/anotherfile.php

      [L]不会阻止生成的URI通过重写引擎返回,它只会停止当前迭代的重写过程。您需要更改正则表达式或添加某种重写条件。一种可能性是在您拥有RewriteRule ^[a-z+]/([a-z]+)?/(.+)$ $2 [L]之前添加{{1}},以便分别处理2个深层目录。

答案 1 :(得分:0)

... Hmmmm

在那里提出一些想法:

  1. 我以为可能会有递归RewriteRule - 但是我不确定,因为你把“最后”规则放在那里。 然而,这是我认为可以解释正在发生的事情的唯一合乎逻辑的事情。

    1. 这与你的Regex没有停止不同 - 在我们告诉它放弃之后,这将是Apache持续很长时间。
  2. 如果Apache没有停止,我不确定你有什么追索权。也许RewriteCondDPI(DPI会丢弃PATH_INFO),分析THE_REQUEST或更多?

  3. 抱歉,我无法提供更多帮助。我希望你在过去一年中解决这个问题。