views:

156

answers:

2

Im really really a newbie in regexp and I can’t figure out how to do that.

My goal is to have the RewriteRule to 'slice' the request URL path in 3 parts:

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

In short, the first segment in the URL path (foo) should be given to a, the second segment (bar) to b, and the rest of the string in c

I wroted this one

<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>

But obviously doesn’t work, and I don’t even know if what I want is possible.

Any suggestion?

EDIT: After playing with coach manager, I got this one working too:

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

What about this:

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

I noticed the following issues with your regex:

  • In your first group, you were only looking for the first character - the + sign after the character group states to match the group with any number of characters as long as there's at least one.

  • You only need one set of brackets to match the sub-expression

  • The ? operator (is this to make the match lazy?) should go straight after the repetition operator (+)

  • I also think the request URI starts with /, which was missing from your regex

  • Your syntax for the optional groups 2 and 3 wasn't quite correct (?:stuff here){0,1} means that "stuff here" may appear or it may not

I've tested this in a great program called The Regex Coach which gives the following

/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
Andy Shellam
why the downvote? If my solution is incorrect please have the courtesy to tell me why. It appears to do the job, as I've now explained in my answer, so I'd appreciate the removal of the downvote.
Andy Shellam
Dont kno who downvoted you, but the first version you posted works, except that the second parameter (bar) is mandatory.. would be great if only the first one would be mandatory. Instead the las version you posted, with the / just after the ^, doesnt work!
DaNieL
This is the version that (according to the regex coach) works - only the first parameter is mandatory (at least one character after the leading /.) I thought Apache starts the URI with a /? If not, just remove the first slash in the regex.
Andy Shellam
No, seem like apache dont start with /, so i removed it and it works.Thanks! Anyway, i updated my answer with another solution (playing with regex coach!)
DaNieL
Andy Shellam
You don’t need ungreedy quantifiers.
Gumbo
A: 

I would probably use this rule (similar to yours):

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

And if you don’t want to allow trailing slashes, you can use this rule to remove them:

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