Redirecionar 301 para replace todos os espaços por hifens

Então aqui está o meu problema. Eu assumi um site que tem um monte de páginas indexadas que têm% 20 indexadas no Google. Isto é simplesmente porque a pessoa decidiu usar apenas o nome da tag como título e slug de URL. Então, os URLs eram algo assim:

http://www.test.com/tag/bob%20hope http://www.test.com/tag/bob%20hope%20is%20funny 

Eu adicionei um novo campo para o slug de url e string substituiu todos os espaços com traços. Embora não tenha problemas para vincular essas novas páginas e obter os dados, preciso redirect 301 as URLs antigas para as novas URLs, o que seria algo como:

 http://www.test.com/tag/bob-hope http://www.test.com/tag/bob-hope-is-funny 

Então, precisa ser capaz de contabilizar vários espaços. Alguma pergunta? 🙂

Use estas regras em seu arquivo .htaccess:

 Options +FollowSymlinks -MultiViews RewriteEngine on RewriteBase / # keep replacing space to hyphen until there is no space use internal rewrite RewriteRule ^([^\s%20]*)[\s%20]+(.*)$ $1-$2 [E=NOSPACE:1] # when there is no space make an external redirection RewriteCond %{ENV:NOSPACE} =1 RewriteRule ^([^\s%20]+)$ $1 [R=301,L] 

Isso replaceá todos os caracteres de espaço ( \s ou %20 ) por hífen -

Então um URI de /tag/bob%20hope%20is%20funny se tornará /tag/bob-hope-is-funny com 301

Breve Explicação: Se houver mais de um espaço no URI, o primeiro RewriteRule será acionado recursivamente, substituindo cada caractere de espaço por hífen - até que não haja mais espaço. Esta regra só irá rewrite internamente.

Uma vez que nenhum espaço é deixado, o segundo RewriteRule é acionado, o qual usa apenas um 301 redirect para o URI convertido.

Baseando-se na resposta do @ anhubhava, ele é próximo, mas também corresponderá a%, 2 ou 0 na URL, e pode causar um loop no apache 2.2 se você não usar o parâmetro DPI. O script completo deve ficar assim:

 Options FollowSymlinks MultiViews RewriteEngine on RewriteBase / # keep replacing space to hyphen until there is no space use internal rewrite RewriteRule ^([^\s%20]*)(?:\s|%20)+(.*)$ $1-$2 [N,E=NOSPACE:1,DPI] # when there is no space make an external redirection RewriteCond %{ENV:NOSPACE} =1 RewriteRule ^([^\s%20]+)$ $1 [R=301,L] 

Eu também adicionei o parâmetro N (Next), pois isso força as regras a serem reavaliadas desde o início, logo após essa regra, se corresponder. Se isso não estiver lá, você pode obter problemas se estiver usando o apache como um proxy reverso, já que é improvável que ele chegue ao fim das reescritas antes que algo mais aconteça.