How to Exclude Specific Path in Nginx Location Regex: Matching All /newsletter/ Except /newsletter/one


3 views

When working with Nginx configuration, there are cases where you need to match all paths under a specific prefix except one particular path. The common approach using location ~ ^/newsletter/(.*)$ will indeed match all paths starting with /newsletter/, but we need to exclude /newsletter/one specifically.

The most elegant solution uses regex negative lookahead:

location ~ ^/newsletter/(?!one($|/)).*$ {
    # Your configuration here
    # This will match /newsletter/anything
    # but NOT /newsletter/one
    # and NOT /newsletter/one/extra
}

For those who prefer different methods, here are two additional solutions:

Method 1: Separate Location Blocks

location = /newsletter/one {
    # Configuration for the excluded path
    # (or empty if you want to bypass it)
}

location /newsletter/ {
    # Configuration for all other newsletter paths
}

Method 2: Using Regex Alternation

location ~ ^/newsletter/((?!one($|/)).*)$ {
    # Configuration here
    # $1 now contains the path after /newsletter/
    # excluding 'one'
}

Here's a complete configuration example for handling newsletter endpoints:

server {
    listen 80;
    server_name example.com;

    # Handle the excluded path
    location = /newsletter/one {
        proxy_pass http://special_backend;
    }

    # Handle all other newsletter paths
    location ~ ^/newsletter/(?!one($|/)).*$ {
        proxy_pass http://regular_backend;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

While negative lookahead works perfectly, it's worth noting:

  • Exact match (location =) is fastest in Nginx
  • Prefix match (location ^~) is faster than regex
  • Complex regex patterns have higher overhead

For high-traffic sites, consider using multiple simple location blocks instead of complex regex.


When working with Nginx location blocks, we often need to match multiple paths under a common prefix while excluding specific routes. In this case, we want to capture all paths starting with /newsletter/ except /newsletter/one.

The basic regex pattern ^/newsletter/(.*)$ correctly matches all newsletter paths, but doesn't provide exclusion capability:

location ~ ^/newsletter/(.*)$ {
    # This matches ALL /newsletter/ paths
    # including /newsletter/one which we want to exclude
}

The most elegant solution uses negative lookahead in regex:

location ~ ^/newsletter/(?!one$).*$ {
    # Configuration for all newsletter paths except /newsletter/one
}

Breaking down the pattern:

  • ^/newsletter/ - matches the base path
  • (?!one$) - negative lookahead ensuring "one" isn't the complete segment
  • .*$ - matches the rest of the path

If negative lookahead isn't supported in your Nginx version, consider these approaches:

Method 1: Exact Match First

location = /newsletter/one {
    # Special handling for the excluded path
}

location /newsletter/ {
    # General handling for all other newsletter paths
}

Method 2: Regex with Alternation

location ~ ^/newsletter/((?!one$).*)$ {
    # Alternative regex approach
}

Always verify your configuration with:

nginx -t
service nginx reload

And test with various URLs to confirm the matching behavior:

  • /newsletter/subscribe - should match
  • /newsletter/one - should NOT match
  • /newsletter/onetwo - should match
  • /newsletter/one/ - should match (trailing slash differs)

Remember that regex locations are evaluated in order and have performance implications. For high-traffic sites, consider organizing your location blocks with exact matches (=) first, then prefixes (^~), then regex matches (~).