Тут дело не в экранировании символов. Функция mod_rewrite работает следующим образом: изменение запроса не заканчивается на последнем правиле RewriteRule. После того, как сработало последнее правило RewriteRule и был добавлен RewriteBase, mod_rewrite проверяет, изменился ли запрос или нет. Если запрос изменился, его обработка начинается заново с начала файла .htaccess.
Чтобы избежать бесконечного цикла исключений, можно добавить следующие условия перед последним правилом RewriteRule:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
Это позволит mod_rewrite понять, что после перенаправления запрос не изменился, и прекратить цикл. В этом случае дополнительное добавление RewriteCond не понадобится.
Еще один способ избежать бесконечного цикла - это не использовать слеш перед "index.php". Таким образом, после перенаправления mod_rewrite сможет определить, что запрос не изменился, и остановить цикл. Правило будет выглядеть следующим образом:
RewriteRule ^([a-zA-Z0-9-_./]+)$ index.php?url=$1 [QSA,L]