How to redirect a url which has space on in it

I am redirecting from this URL

www.example.com/article.php?id=12&title=some-title

to this URL

www.example.com/article/12/some-title

Using these URL rewriting rules

RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /(article)\.php\?id=(\d+)&title=([\w-]+)\ HTTP
RewriteRule ^article\.php$ /%1/%2/%3? [R=301,L]
RewriteRule ^article/(\d+)/([\w-]+)$ article.php?id=$1&title=$2[R=301,L]

But if the URL has a space in it for example

www.example.com/article.php?id=12&title=some%20title

Then the above rule will not work. How can I make this URL work with the rule mentioned above only using .htaccess?


RewriteRule ^article/(\d+)/([\w-]+)$ article.php?id=$1&title=$2[R=301,L]

Bit of a side issue, but you are missing a space before the RewriteRule flags which will result in an erroneous rewrite. It should be: ...&title=$2 [R=301,L].

With regards to the space character (%20 when URL/percent encoded)... the THE_REQUEST contains the URL encoded character, but the URL-path matched against the RewriteRule pattern is URL decoded (ie. a literal space). In the above example, this means two different regex patterns. So, in order to match a space in the title you can modify your existing rules something like:

RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /(article)\.php\?id=(\d+)&title=([\w%-]+)\ HTTP
RewriteRule ^article\.php$ /%1/%2/%3? [NE,R=301,L]
RewriteRule ^article/(\d+)/([\w\s-]+)$ article.php?id=$1&title=$2 [R=301,L]

Each directive is modified slightly.

  • The CondPattern now allows for a literal percent character (ie. [\w%-]).
  • The NE flag is required on the following RewriteRule to prevent the URL encoded space from being double encoded (eg. %2520).
  • And the last RewriteRule requires \s (any whitespace character) being added to the pattern. (Alternatively, you could just use a backslash escaped space, ie. \, or just a space and surround the entire pattern in double quotes.)

This just permits the additional space. Although the CondPattern now allows any percent encoded character, the RewriteRule pattern restricts this to whitespace.


UPDATE#1: To allow some additional characters... [\w%-] (everything between the square brackets) is a regex character class. To allow more characters you just add these characters to the character class. eg. In the case of ,, ' and ;, this becomes [\w%,';-]. Note that the hyphen (-) must appear at the start or end of the character class, since it is a special meta character.

To allow any characters then you can change the pattern to .+. Which is simply 1 or more characters. The dot indicates any character. So, this would become:

RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /(article)\.php\?id=(\d+)&title=(.+)\ HTTP
RewriteRule ^article\.php$ /%1/%2/%3? [NE,R=301,L]
RewriteRule ^article/(\d+)/(.+) article.php?id=$1&title=$2 [R=301,L]