I have got a situation where I want to rewrite the following URLs and send my first URL parameter as data parameter and rest as query parameter
www.example.com/anything.jpg //Skip - Do Nothing because its a file from root
www.example.com/anything //anything == ?data=$1
www.example.com/something/b //something == ?data=$1 b == &query=$2
www.example.com/certainly/b/c //certainly == ?data=$1 b/c == &query=$2
www.example.com/anything/b/c.jpg //anything == ?data=$1 b/c.jpg == &query=$2
www.example.com/but/b/c/d //but == ?data=$1 b/c/d == &query=$2
so my first URL parameter will always be data and rest as query no matter what it has. I found this question here htaccess redirect only if it has value after forward slash and got it to some extent like
rewrite ^/(.*)/(.+)$ /handle.php?data=$1&query=$2 last;
It has some problems as this rewrites into following
www.example.com/anything.jpg //Results in 404 Not Found
www.example.com/anything //Results in 404 Not Found
www.example.com/something/b //Working good
www.example.com/certainly/b/c //data=certainly/b query=c
www.example.com/anything/b/c.jpg //data=certainly/b query=c.jpg
www.example.com/but/b/c/d //data=but/b/c query=d
I tried playing around with different variations in rewrite ^/(.*)/(.+)$ /handle.php?data=$1&query=$2 last; but nothing worked
So that I can prove the regex matching outcomes, I'll demonstrate with preg_replace(), but the pattern should seamlessly translate to your script.
Code: (Demo)
$urls = [
'www.example.com/anything.jpg', //Skip - Do Nothing because its a file from root
'www.example.com/anything', //anything == ?data=$1
'www.example.com/something/b', //something == ?data=$1 b == &query=$2
'www.example.com/certainly/b/c', //certainly == ?data=$1 b/c == &query=$2
'www.example.com/anything/b/c.jpg', //anything == ?data=$1 b/c.jpg == &query=$2
'www.example.com/but/b/c/d', //but == ?data=$1 b/c/d == &query=$2
];
var_export(
preg_replace('~www\.example\.com/(?![^/]+\.jpg)([^/]+)(?:/(.+))?~', 'www.example.com?data=$1&query=$2', $urls)
);
Output:
array (
0 => 'www.example.com/anything.jpg',
1 => 'www.example.com?data=anything&query=', // note the empty query value
2 => 'www.example.com?data=something&query=b',
3 => 'www.example.com?data=certainly&query=b/c',
4 => 'www.example.com?data=anything&query=b/c.jpg',
5 => 'www.example.com?data=but&query=b/c/d',
)
Using a negated character class containing the slash for the first capture group will permit greedy (speedy) matching without matching too much.
The negative lookahead prevents matching a jpg file.
The second capture group is optional, so unless you want to write a separate pattern to match data-only urls, you'll need to tolerate the empty assignment.
For your purposes, my untested suggestion is:
One declaration:
rewrite ^/(?![^/]+\.jpg)([^/]+)(?:/(.+))?$ /handle.php?data=$1&query=$2 last;
Or as two declarations:
rewrite ^/(?![^/]+\.jpg)([^/]+)$ /handle.php?data=$1 last;
rewrite ^/(?![^/]+\.jpg)([^/]+)/(.+)$ /handle.php?data=$1&query=$2 last;