Nginx location matching with regex year/month/day/*

I have some old url pattern to redirect to new location in nginx.

A typical clean url looks like example.com/2021/06/13/78676.html?..

Im roughly trying to match number of digit in each block like:

location ~ "^[0-9]{4}/[0-9]{2}/[0-9]{2}/([0-9]+).html" {
   rewrite ^ /archive.php?q=$1;
}

Where exactly Im going wrong please..


Solution 1:

The first issue is that all Nginx URIs begin with a leading /. So your regular expression will never match.

The second issue is that numeric captures are overwritten whenever a new regular expression is evaluated. So in your configuration, $1 will always be empty.

You could use a named capture:

location ~ "^/[0-9]{4}/[0-9]{2}/[0-9]{2}/(?<value>[0-9]+)\.html" {
    rewrite ^ /archive.php?q=$value last;
}

Alternatively, place the numeric capture in the rewrite statement:

rewrite "^/[0-9]{4}/[0-9]{2}/[0-9]{2}/(?<value>[0-9]+)\.html" /archive.php?q=$1 last;

Or use a try_files statement instead of rewrite:

location ~ "^/[0-9]{4}/[0-9]{2}/[0-9]{2}/([0-9]+)\.html" {
    try_files nonexistent /archive.php?q=$1;
}