mod_rewrite 具有多个嵌入匹配

发布于 2024-09-30 08:49:58 字数 890 浏览 0 评论 0 原文

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

RewriteRule ^([^/]+)/([^/]+)/(tab:([^/]+)/?)?(scope: ([^/]+)/?)?(排序:([^/]+)/?)?(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:搜索/。其他参数也类似。

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

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

I have the following rewrite rule in my .htaccess file:

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

It seems to work great when testing on some of the online regex testers that I have found.
However on this tester (which seems to be a better tester and represents exactly what I am seeing when I try to apply this rule I am seeing some strange things. http://civilolydnad.se/projects/rewriterule/

Lets way I apply it to this url:
view1/harry+potter/tab:search/scope:blah/sort:cdate

What I get is web/results.php?view=view1&q=harry+potter&tab=tab:search/&scope=scope:blah/&sort=sort:cdate&p=0

What is strange to me is that I should be getting tab=search not tab=tab:search/. And the other parameters are similar.

The matching regex group 4 contains search, but if I don't use group 3 ($3) somewhere in the query, I don't get access to $4.

I must be doing something wrong. Any suggestions?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

以往的大感动 2024-10-07 08:49:58

我什至无法让该测试仪工作(它不返回任何结果),因此可以安全地假设是测试仪出了问题,而不是您。另外,您的规则当前存在语法错误(不匹配的右括号),因此我假设您的意思是这样的:

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

使用提供的示例 URL 在我的测试服务器上运行它几乎会返回您实际期望的结果。 page 参数永远不会获得预期值,因为 $10 不是 有效的 RewriteRule 反向引用

反向引用是 $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 与 print_r($_GET) 给出:

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

I wasn't able to even get that tester to work (it doesn't return any results), so it's safe to assume that it's the tester that's wrong, not you. Also, your rule currently has a syntax error (unmatched closing parenthesis), so I'm going to assume that you meant this:

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

Running this on my test server with the example URL provided returns the results that you were actually expecting, almost. The page parameter will never get the expected value because $10 is not a valid RewriteRule backreference:

Back-references are identifiers of the form $N (N=0..9), which will be replaced by the contents of the Nth group of the matched Pattern

This leaves you with the following capture groups:

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

However, since mod_rewrite allows PCRE and you don't actually need all of the information that's currently captured, you can just use non-capturing groups as in the following test pattern:

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

Now we just have backreferences for the relevant portions of data, giving this modified 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]

With this, going to view1/harry+potter/tab:search/scope:blah/sort:cdate with a print_r($_GET) gives:

Array (
    [view] => view1
    [q] => harry potter
    [tab] => search
    [searchscope] => blah
    [sortBy] => cdate
    [p] =>
)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文