RewriteEngine:URL中的查询工作不正确。也许正则表达式错了?

时间:2013-11-21 16:43:10

标签: regex .htaccess mod-rewrite

我有这样的网址:

index.php?lang=de&menu=products&sub1=heat&sub2=M123

只有字段“lang”是强制性的,所以我的.htaccess看起来像这样:

RewriteRule ^(de|at|ch|it|nl)/?(.*)/?(.*)/?(.*)$ index.php?lang=$1&menu=$2&sub1=$3&sub2=$4

当我阅读$ _GET时,我得到了以下代码......但我希望填充所有变量

[lang] => at
[menu] => products/heat/M123
[sub1] => 
[sub2] => 

这是我第一次使用正则表达式和重写引擎。这可能是一个愚蠢的问题。

1 个答案:

答案 0 :(得分:3)

使用相同的替换字符串尝试以下操作:

^(de|at|ch|it|nl)(?:/([^/]*))?(?:/([^/]*))?(?:/([^/]*))?$

所以:

RewriteRule ^(de|at|ch|it|nl)(?:/([^/]*))?(?:/([^/]*))?(?:/([^/]*))?$ index.php?lang=$1&menu=$2&sub1=$3&sub2=$4

Working on RegExr


<强>解释

.*贪婪,因为第一个.*之后的所有字符都不匹配(/?而其余的.*都可以幸福地匹配任何内容匹配字符串的其余部分,所有其他组最终为0长度匹配。

通常通过制作.*懒惰 - .*?来修复问题,但在这种情况下(我通过测试失败发现),延迟量词仍将匹配字符串的结尾,因为它会看起来它需要具体的东西来匹配,显然匹配一个可选的/是不够的。

为了解决这个问题,我将/?.*替换为(?:/([^/]*))?

(?: .... )只是意味着不要捕获这个组(如$ 1 $ 2等)。

因此忽略了每个组都有(/([^/]*))?

每个组都是可选的,必须与/后跟0个non-/个字符匹配。这样你可以确定*不会贪婪并消耗下一组。

一个稍微短的正则表达式也可以(我原来的)但有点难以解释:

^(de|at|ch|it|nl)(?:/(.*?))?(?:/(.*?))?(?:/(.*?))?$