Categories: php, apache, nginx, url, url-rewriting

Rewrite URL to specifi query parts Nginx

1 answer

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

Received answer to this question:
The best answer according to the author of the question:

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.