mod_rewrite有多个嵌入的匹配项

时间:2010-10-28 21:17:34

标签: regex mod-rewrite

我的.htaccess文件中有以下重写规则:

RewriteRule ^([^/]+)/([^/]+)/(tab:([^/]+)/?)?(scope:([^/]+)/?)?(sort:([^/]+)/?)?(p:\d+)/?)?$ web/results.php?view=$1&q=$2&tab=$4&searchscope=$6&sortBy=$8&page=$10 [NC,QSA,L]

在对我发现的一些在线正则表达式测试人员进行测试时似乎工作得很好。 然而,对于这个测试人员(这似乎是一个更好的测试人员,并且代表了我在尝试应用此规则时所看到的内容,我看到了一些奇怪的事情。http://civilolydnad.se/projects/rewriterule/

让我将它应用于此网址: view1/harry+potter/tab:search/scope:blah/sort:cdate

我得到的是web/results.php?view=view1&q=harry+potter&tab=tab:search/&scope=scope:blah/&sort=sort:cdate&p=0

对我来说,奇怪的是我应该tab=search而不是tab=tab:search/。其他参数相似。

匹配的正则表达式组4包含search,但如果我在查询中的某处不使用组3($ 3),则无法访问$ 4。

我一定是做错了。有什么建议吗?

1 个答案:

答案 0 :(得分:0)

我甚至无法让测试人员工作(它不会返回任何结果),因此可以安全地假设测试人员错了,而不是你。此外,您的规则目前有语法错误(不匹配的右括号),所以我假设你的意思是:

RewriteRule ^([^/]+)/([^/]+)/(tab:([^/]+)/?)?(scope:([^/]+)/?)?(sort:([^/]+)/?)?(p:(\d+)/?)?$ web/results.php?view=$1&q=$2&tab=$4&searchscope=$6&sortBy=$8&page=$10 [NC,QSA,L]

使用提供的示例网址在我的测试服务器上运行此命令几乎可以返回您实际期望的结果。页面参数永远不会达到预期值,因为$10不是valid RewriteRule backreference

  

反向引用是$ N(N = 0..9)形式的标识符,将被匹配模式的第N组内容替换

这将为您留下以下捕获组:

RewriteRule ^([^/]+)/([^/]+)/(tab:([^/]+)/?)?(scope:([^/]+)/?)?(sort:([^/]+)/?)?(p:(\d+)/?)?$
#           ^|     | |     | |    |     |  | |     *|     |  | |     |     |  | |         | ^
#            |     | |     | |    |     |  | |     0|     |  | |     |     |  | |         |
#            ^  *  ^ ^  *  ^ ^    | *   |  ^ ^      |*    |  ^ ^     | *   |  ^ ^    *    ^
#               1       2         | 3   |           |5    |          | 7   |         9
#                                 ^  *  ^           ^  *  ^          ^  *  ^
#                                    4                 6                8

但是,由于mod_rewrite允许PCRE并且您实际上并不需要当前捕获的所有信息,因此您可以像以下测试模式一样使用非捕获组:

^([^/]+)/([^/]+)/(?:tab:([^/]+)/?)?(?:scope:([^/]+)/?)?(?:sort:([^/]+)/?)?(?:p:(\d+)/?)?$

现在我们只对数据的相关部分进行反向引用,给出这个修改过的RewriteRule:

RewriteRule ^([^/]+)/([^/]+)/(?:tab:([^/]+)/?)?(?:scope:([^/]+)/?)?(?:sort:([^/]+)/?)?(?:p:(\d+)/?)?$ web/results.php?view=$1&q=$2&tab=$3&searchscope=$4&sortBy=$5&page=$6 [NC,QSA,L]

有了这个,转到 view1 / harry + potter / tab:search / scope:blah / sort:cdate with print_r($_GET)给出:

Array (
    [view] => view1
    [q] => harry potter
    [tab] => search
    [searchscope] => blah
    [sortBy] => cdate
    [p] =>
)