Since your parameters are optional, you want to make the whole capture groups optional, not just your slashes. To accomplish this we can use non-capturing groups.
RewriteRule ^([^/]+)(?:/([^/]*))?(?:/([^/]*))?(?:/([^/]*))?(?:/([^/]*))?(?:/([^/]*))?(?:/([^/]*))?(?:/([^/]*))?$ /index.php?service=$1&p1=$2&p2=$3&p3=$4&p4=$5&p5=$6&p6=$7&p7=$8 [L]
([^/]+)
captures the service. It is not optional, and should always be there. The [^/]
part matches a character that is not a slash... and we match at least one, and as much as we can. Then we use groups of (?:/([^/]*))?
to capture each argument. The ?:
syntax marks a group as non-capturing. The contents will not be used for the $x
replacement strings. The ?
behind the whole non-capturing group makes it an optional argument. The inner capture group will be used for the replacement later on. All replacement strings are replaced by something. If nothing is matched for a particular replacement group, it is replaced by the empty string.
An url like http://example.com/service/param1/param2/param3/
will result in an url as http://example.com/index.php?service=service&p1=param1&p2=param2&p3=param3&p4=&p5=&p6=&p7=
.
If you want to match more than 8 optional parameters, you are better off passing the request on to a php router. If you have key-value pairs as path segments, this answer may help you.