I want to replace each + with (space) in $args.
I know the solution of
if ($args ~ ^(.*)\+(.*)$) {
return 301 "$uri?$1 $2";
}
However that's not ideal because there's a redirect for each +. Is there a better solution?
You could use more than one regular expression. Each regular expression tests the $args parameter for one, two, three, etc. + characters (evaluated in reverse order) which will minimise the recursion.
A compact solution uses a map to define the regular expressions.
For example:
map $args $spaces {
default 0;
~^(.*)\+(.*)\+(.*)\+(.*)\+(.*)$ "$1 $2 $3 $4 $5";
~^(.*)\+(.*)\+(.*)\+(.*)$ "$1 $2 $3 $4";
~^(.*)\+(.*)\+(.*)$ "$1 $2 $3";
~^(.*)\+(.*)$ "$1 $2";
}
server {
...
if ($spaces) { return 301 "$uri?$spaces"; }
...
}
You can use more or less regular expressions to optimise the solution. The above will generate one redirection for up to four + characters, and two redirections for between five and eight + characters, and so on.
See this document for details.