rewrite nginx not capture optional value

Anto asked:

I’m migrating a configuration to a new CMS and there are urls with the structure in the current page “/view-article/ID”, some shortening of links added parameters to the end as “/view-article/ID/{RAMDON|undefined|others}”.

I want to redirect this url to the new structure “/id/ID”, but I am doing tests on online publishers of PCRE regular expressions, before putting it into production and I can not create a regular expression to match to the url of the CMS and to which added the shortening (discarding the parameters that add).

My settings in the following:

location ~* ^/view-article {

    #rewrite ^/view-article/(.*)(?:\/.+) $scheme://$host/id/$1 permanent;
    rewrite ^/view-article/(.*) $scheme://$host/id/$1 permanent;

Examples of the current url and should be in the new cms:

/view-article/45356 -> /id/45356
/view-article/4a57f -> /id/4a57f
/view-article/4a57f/undefined -> /id/4a57f 
/view-article/4a57f/ramdon -> /id/4a57f
/view-article/4a57f/88484 -> /id/4a57f
/view-article/aabb3/jddt65 -> /id/aabb3

Do you think that it is correct? How do I make it work? Thanks

My answer:

You don’t want to capture everything, only text from the ID up to the next slash, if any. So (.*) won’t do what you want, since it just captures everything.

Rather, capture until the following slash (if it exists):

rewrite ^/view-article/([^/]+) /id/$1 permanent;

(There’s also no reason to reconstruct the whole URL yourself when a relative URL will suffice. Nor is there a reason to put this in a special location, so don’t bother.)

View the full question and any other answers on Server Fault.

Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.