我有这样的网址:
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] =>
这是我第一次使用正则表达式和重写引擎。这可能是一个愚蠢的问题。
答案 0 :(得分:3)
使用相同的替换字符串尝试以下操作:
^(de|at|ch|it|nl)(?:/([^/]*))?(?:/([^/]*))?(?:/([^/]*))?$
所以:
RewriteRule ^(de|at|ch|it|nl)(?:/([^/]*))?(?:/([^/]*))?(?:/([^/]*))?$ index.php?lang=$1&menu=$2&sub1=$3&sub2=$4
<强>解释强>
.*
贪婪,因为第一个.*
之后的所有字符都不匹配(/?
而其余的.*
都可以幸福地匹配任何内容匹配字符串的其余部分,所有其他组最终为0长度匹配。
通常通过制作.*
懒惰 - .*?
来修复问题,但在这种情况下(我通过测试失败发现),延迟量词仍将匹配字符串的结尾,因为它会看起来它需要具体的东西来匹配,显然匹配一个可选的/
是不够的。
为了解决这个问题,我将/?.*
替换为(?:/([^/]*))?
。
(?: .... )
只是意味着不要捕获这个组(如$ 1 $ 2等)。
因此忽略了每个组都有(/([^/]*))?
。
每个组都是可选的,必须与/
后跟0个non-/
个字符匹配。这样你可以确定*不会贪婪并消耗下一组。
一个稍微短的正则表达式也可以(我原来的)但有点难以解释:
^(de|at|ch|it|nl)(?:/(.*?))?(?:/(.*?))?(?:/(.*?))?$