Недавно, при работе над своим проектом (сайт со статьями на тему «как сделать»), столкнулся с проблемой в работе mod_rewrite. Суть проблемы заключалась в следующем: в облаке тегов, при переходе на тег «C++» (обработанный urlencode и ставший C%2B%2B) я попадал на тег «С » (буква «С» и 2 пробела).

Правило в .htaccess было таким:

RewriteRule ^tag/([^/]+)/$ index.php?tag=$1 [L]

Путем экспериментов выяснил, что в $1 правила попадает не «C%2B%2B», а «C++» (внутри апача %2B превращается в +). Плюс, естественно, расценивался как пробел, соединяющий два слова.

Долго копал интернет в поисках решения, экспериментировал с флагами, пока по запросу в гугле «C++ mod_rewrite» не нашел пост с описанием данного бага апача где-то на просторах форумов на apache.org (насколько я понял из этого поста — моя проблема это баг апача).

В этом посте автор советовал разбирать регулярками %{THE_REQUEST}, в котором «C%2B%2B» был в исходной форме, а не заменялся на «C++». В %{THE_REQUEST} обычно содержится что-то наподобие «GET tag/C%2B%2B/ HTTP 1.1».

Прием помог, я переделал старое рерайт-правило на такое:

RewriteCond %{THE_REQUEST} ^GET[\ ]+/tag/([^/]+)/[\ ]+HTTP.*$
RewriteRule ^(.*)$ index.php?tag=%1 [L]

Проверено на версиях апача 2.2 (винда) и 1.3.4 (линукс).

Теперь пользователи моего сайта могут без проблем читать статьи с тегом «C++» :)
Надеюсь, мой пост поможет кому-нибудь в аналогичной проблеме.