Apache RewriteRule: возможно ли «обнаружить» первый и второй сегмент пути? - PullRequest
1 голос
/ 25 марта 2010

Я действительно новичок в регулярных выражениях, и я не могу понять, как это сделать.

Моя цель состоит в том, чтобы 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>

Но, очевидно, это не работает, и я даже не знаю, возможно ли то, что я хочу.

Есть предложения?

EDIT: После игры с тренером-тренером у меня тоже получилось:

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

Ответы [ 2 ]

1 голос
/ 25 марта 2010

Я бы, наверное, использовал это правило (аналогично вашему):

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

И если вы не хотите разрешать конечные слэши, вы можете использовать это правило для их удаления:

RewriteRule (.*)/$ /$1 [L,R=301]
0 голосов
/ 25 марта 2010

Что по этому поводу:

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

Я заметил следующие проблемы с вашим регулярным выражением:

  • В вашей первой группе вы искали только первый символ - знак + после состояния группы символов соответствует группе с любым количеством символов, если есть хотя бы один.

  • Вам нужен только один набор скобок, чтобы соответствовать подвыражению

  • ? оператор (это сделать совпадение ленивым?) должен идти сразу после оператора повторения (+)

  • Я также думаю, что URI запроса начинается с /, который отсутствует в вашем регулярном выражении

  • Ваш синтаксис для необязательных групп 2 и 3 был не совсем корректным (?:stuff here){0,1} означает, что может появиться "здесь" или нет

Я проверил это в замечательной программе под названием 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
...