How would I go about rewriting:




I want to remove all instances on aff=x regardless of how many other parameters in the URL.


I want to remove all instances on aff=x regardless of how many other parameters in the URL.

Assuming you want to keep any other URL parameters (in any order) and simply remove the aff=number parameter, then you can do something like the following using mod_rewrite in the root .htaccess file:

RewriteCond %{QUERY_STRING} ^(.*&|)aff=\d+(?:&(.*)|)$
RewriteRule (.*) /$1?%1%2 [R=302,L]

This will need to go before the existing WordPress directives.

This assumes that if the aff parameter is present it will have a value of only digits and at least 1 digit.

The $1 is a backreference to the captured RewriteRule pattern. So, this will handle any URL-path, not just the document root, as in your example.

%1 and %2 are backreferences to the captured groups in the previous CondPattern. %1 is before the parameter to be removed and %2 is after. Both are optional.

Change the 302 (temporary) redirect to 301 (permanent) only after you have confirmed this is working OK (if this is intended to be permanent).

UPDATE#1: Query string contains %-encoded characters

If any of the other URL parameters (that you want to keep) contain URL-encoded (%-encoded) values then you will need to add the NE (noescape) flag to the RewriteRule directive to prevent these characters from being doubly encoded in the substitution. For example:

RewriteRule (.*) /$1?%1%2 [NE,R=302,L]

The QUERY_STRING server variable is not %-decoded by Apache. Normally, mod_rewrite URL-encodes the substitution before sending the response back to the client. But this will doubly encode any already-encoded characters that we have captured from the query string. The NE flag prevents this from happening.

UPDATE#2: URL parameter value to be removed could be anything

The question specifically dealt with removing a URL parameter called aff that contained a "number". Generally, you should be as specific as possible when dealing with regex, however, if the URL parameter to be removed can contain anything then modify the CondPattern to be something like one of the following

  • ^(.*&|)aff=.*?(?:&(.*)|)$ - a non-greedy match of 0 or more characters.
  • ^(.*&|)aff=[^&]*(?:&(.*)|)$ - matches anything except & (URL parameter delimiter) 0 or more times.

The important point in both of these regex is that the value being matched is not captured, ie. must not be surrounded in plain parentheses.

In summary:

RewriteCond %{QUERY_STRING} ^(.*&|)aff=[^&]*(?:&(.*)|)$
RewriteRule (.*) /$1?%1%2 [NE,R=302,L]
  • This solution doesn’t work when a parameter contains a non-ASCII character: How do I use this snippet, but keep a parameter such as x=é, which with the code above, redirects to example.com/?x=%25C3%25A9 instead of example.com/?x=%C3%A9 – Lucas Nov 12 '18 at 22:27
  • 1
    @Lucas You'll need to add the NE flag to the RewriteRule directive. I've updated my answer. – MrWhite Nov 12 '18 at 22:53
  • The NE does indeed protect the characters from being doubly escaped, but now the x=é (or aff=é) parameter is not being removed. If it is the final parameter, I am able to force it to work by using the following as my RewriteCond, but I understand that I’m catching to much with the first (.*) here: RewriteCond %{QUERY_STRING} ^(.*&|)aff=(.*)+(?:&(.*)|)$ – Lucas Nov 13 '18 at 17:16
  • 1
    "but now the x=é (or aff=é) parameter is not being removed" - The question specifically dealt with number values, so that is correct, it shouldn't be removed. You also stated in your first comment, "keep a parameter such as x=é" - you can't "remove" and "keep" the same parameter. However, if the URL param to be removed can itself contain anything then you will need to modify the regex. The problem with your suggestion is that it is indeed matching too much (greedy), but you are also capturing the pattern so the backreference will be incorrect. I've updated my answer. – MrWhite Nov 14 '18 at 2:28
  • @Lucas How did you get on with the last update? – MrWhite Nov 17 '18 at 22:01

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.