Have an issue where nginx isn't passing on the last forward slash of an arg to a script

Example https://xxxx.com/test_t/company/Default/icon_category/Hotel.png

location / {​​
rewrite "^/([a-zA-Z0-9]+.*)/([a-zA-Z0-9]+.*)$"
/test2.php?t=$1&file=$2 last;

test2.php is just simply getting and echoing $t and $file

Actual outcome: test_t/company/Default/icon_categoryHotel.png

Expected outcome: test_t/company/Default/icon_category/Hotel.png

  • basically the contents of the 1st forward slash goes to ?t=$1 everything after this should go to $2 including all forward slashes – Viet Le Mar 3 at 5:16

You say that you want the first path component, without any slashes, to be in the first variable, and everything after it, including slashes, in the second variable.

Let's see how your current regex looks, at regex101:


When we give it the string to match: /test_t/company/Default/icon_category/Hotel.png the first group is test_t/company/Default/icon_category and the second group is Hotel.png.

The reason for this is that the first group is followed by a literal character /, and the .* match quantifier is greedy, meaning in this case it will keep going until the last / in the string after the capture group. This is why you see nearly the entire path in the first variable.

To fix that, you need to make the quantifier lazy, so that it stops matching at the first occurrence of whatever comes after it in the regex. To accomplish this we change .* to .*?.

Now on regex101 you can see the first capture group is test_t as you wanted, but the second capture group does not include the forward slash. This is because the literal / is between the two capture groups, thus it won't be included in either of them.

Because you want it to be included in the second variable, we will move it inside the second capture group, so /( becomes (/. Here is how the third iteration looks on regex101.


This results in the first variable being test_t and the second being /company/Default/icon_category/Hotel.png.

If you want to make further changes, you can try them out on regex101 yourself to see the results instantly. This way you can learn how everything works before you make any changes to your live configuration.

  • Actually the regex ([a-zA-Z0-9]+.*?) looks unnecessarily complex to me. I would use simply ([^/]+) as the regular expression, or if one wants to enforce first letter being alphanumeric, then ([a-zA-Z0-9][^/]*). – Tero Kilkanen Mar 3 at 15:52
  • 1
    @TeroKilkanen Good advice, but I deliberately focused only on making the specific changes the user requested. – Michael Hampton Mar 3 at 16:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.