【问题标题】:Apache RewriteRule: it is possible to 'detect' the first and second path segment?Apache RewriteRule:可以“检测”第一个和第二个路径段吗?
【发布时间】:2010-03-25 10:04:08
【问题描述】:

我真的是 regexp 的新手,我不知道该怎么做。

我的目标是让RewriteRule 将请求 URL 路径“切片”为 3 部分:

example.com/foo
#should return: index.php?a=foo&b=&c=

example.com/foo/bar
#should return: index.php?a=foo&b=bar&c=

example.com/foo/bar/baz
#should return: index.php?a=foo&b=bar&c=baz

example.com/foo/bar/baz/bee
#should return: index.php?a=foo&b=bar&c=baz/bee

example.com/foo/bar/baz/bee/apple
#should return: index.php?a=foo&b=bar&c=baz/bee/apple

example.com/foo/bar/baz/bee/apple/and/whatever/else/no/limit/in/those/extra/parameters
#should return: index.php?a=foo&b=bar&c=baz/bee/apple/and/whatever/else/no/limit/in/those/extra/parameters

简而言之,应将 URL 路径中的第一段 (foo) 赋予 a,将第二段 (bar) 赋予 b,并且c

中的其余字符串

这是我写的

<IfModule mod_rewrite.c>
  RewriteEngine on
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteCond %{REQUEST_URI} !=/favicon.ico
  RewriteRule ^(([a-z0-9/]))?(([a-z0-9/]+))?(([a-z0-9]+))(.*)$ index.php?a=$1&b=$2&c=$3 [L,QSA]
</IfModule>

但显然行不通,我什至不知道我想要的是否可行。

有什么建议吗?

编辑: 在和教练经理玩之后,我也得到了这个:

RewriteRule ^([^/]*)?/?([^/]*)?/?(.*)?$ index.php?a=$1&b=$2&c=$3 [L,QSA]

【问题讨论】:

    标签: regex apache mod-rewrite url-rewriting


    【解决方案1】:

    我可能会使用这个规则(类似于你的):

    RewriteRule ^([^/]+)?/?([^/]+)?/?(.*) index.php?a=$1&b=$2&c=$3 [L,QSA]
    

    如果您不想允许尾部斜杠,您可以使用此规则将其删除:

    RewriteRule (.*)/$ /$1 [L,R=301]
    

    【讨论】:

      【解决方案2】:

      这个呢:

      RewriteRule ^/([a-z0-9]+?)(?:/([a-z0-9]+?)){0,1}(?:/(.*)){0,1}$ [L,QSA]
      

      我注意到您的正则表达式存在以下问题:

      • 在您的第一个组中,您只查找第一个字符 - 字符组后面的 + 号表示该组与任意数量的字符匹配,只要至少有一个。

      • 你只需要一组括号来匹配子表达式

      • ?运算符(这是为了使匹配变得懒惰吗?)应该直接在重复运算符(+)之后进行

      • 我还认为请求 URI 以 / 开头,而您的正则表达式中缺少它

      • 您的可选组 2 和 3 的语法不太正确(?:stuff here){0,1} 意味着“这里的东西”可能会出现,也可能不会出现

      我已经在一个名为 The Regex Coach 的出色程序中对此进行了测试,它给出了以下结果

      /foo (or /foo/) = index.php?a=foo&b=&c=
      /foo/bar (or /foo/bar/) = index.php?a=foo&b=bar&c=
      /foo/bar/any/number/of/other/parameters/after/the/third/one = index.php?a=foo&b=bar&c=any/number/of/other/parameters/after/the/third/one
      

      【讨论】:

      • 为什么投反对票?如果我的解决方案不正确,请礼貌地告诉我原因。正如我现在在回答中所解释的那样,它似乎可以完成这项工作,所以我很感激取消投票。
      • 不知道谁对您投了反对票,但您发布的第一个版本有效,除了第二个参数(bar)是强制性的。如果只有第一个是强制性的,那就太好了。相反,您发布的 las 版本,在 ^ 之后带有 /,不起作用!
      • 这是(根据正则表达式教练)有效的版本 - 只有第一个参数是强制性的(前导 / 后至少有一个字符。)我认为 Apache 以 / 开头的 URI?如果没有,只需删除正则表达式中的第一个斜杠。
      • 不,似乎 apache 不以 / 开头,所以我删除了它并且它可以工作。谢谢!无论如何,我用另一个解决方案更新了我的答案(与正则表达式教练一起玩!)
      • 那个不太行 - 它允许一个空字符串,并将你的第一个参数分配给第二个 - 所以 /foo/bar/third 变成 index.php?a=&b=foo&c= bar/third,并且只允许一个参数(你说前两个是强制性的)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-31
      • 1970-01-01
      相关资源
      最近更新 更多