mod_rewrite: substitua sublinhados por traços

Estou revelando minha desconcertante vergonha do REGEX-fu aqui, mas: Atualmente eu tenho um site onde uma carga de URLs dos artigos é escrita como “article_name”, enquanto as mais recentes são escritas como “article-name”.

Eu quero mover todos eles para usar traços, então há uma expressão regular que eu poderia usar para rewrite as URLs mais antigas para seus equivalentes mais novos?

Agradecendo antecipadamente!

Primeiro você deve conseguir consistência nas URLs existentes. Basicamente, você tem que normalizar todos os nomes existentes para sempre usar traços. Ok, você fez isso.

Estamos começando com a seguinte suposição:

A URL é mais ou menos da seguinte forma:

 http://example.com/articles/what-ever/really-doesnt_matter/faulty_article_name

onde somente URLs sob /articles devem ser reescritos, e somente a parte /faulty_article_name precisa ser desinfetada.

Muito atualizado, com algo que realmente funciona

Para o Apache:

 RewriteEngine On RewriteRule ^(/?articles/.*/[^/]*?)_([^/]*?_[^/]*)$ $1-$2 [N] RewriteRule ^(/?articles/.*/[^/]*?)_([^/_]*)$ $1-$2 [R=301] 

Isso geralmente é inspirado pela resposta da GApple.

O primeiro /? garante que esse código seja executado nos arquivos vhost confs e .htaccess . Este último não espera uma barra inicial.

Em seguida, adiciono os articles/ peças para garantir que as regras se apliquem apenas a URLs em /articles .

Então, enquanto temos pelo menos dois sublinhados na URL, continuamos fazendo as regras. Quando acabamos com apenas um sublinhado restante, a segunda regra entra em ação, substitui-a por um traço e faz um redirecionamento permanente.

Ufa

Tente isto:

 RewriteRule ^([^_]*)_([^_]*_.*) $1-$2 [N] RewriteRule ^([^_]*)_([^_]*)$ /$1-$2 [L,R=301] 

A primeira regra substitui um sublinhado de cada vez até que haja um ou menos à esquerda. A última regra replaceá o último underscrore e fará um redirecionamento externo.

Uma abordagem potencialmente diferente para pensar:

Eu estou supondo que o seu “formato antigo” e seu “novo formato” estarão em diretórios diferentes para essa idéia, se eles não são, você pode querer considerar fazer o novo formato ter um nome de diretório diferente.

Por exemplo:

  http://site.com/articles/2008/12/31/new_years_celebration 
  http://site.com/article/2008/12/31/new-years-celebration 

Nesse caso, você poderia usar mod_rewrite para detectar qualquer coisa no “diretório antigo” e redirecioná-lo para um ” redirector.php “.

Embora pensando duas vezes, seu mod_rewrite poderia procurar algo como isto:

  RedirectRule /articles/(.*_.*) /redirector.php?article=$1 

Combinando qualquer coisa com um _ e enviando pelo redirecionador.

Dentro de redirector.php você pode obter o $_SERVER['REQUEST_URI'] e usar ferramentas como preg_replace e até mesmo consultas ao database para encontrar o URL correto para redirecioná-las – assim como estudar o número de accesss para URLs antigos.

Aqui está um método: http://yoast.com/apache-rewrite-dash-underscore/

Basicamente, ele separa o url em tokens em ambos os lados do sublinhado e reescreve os tokens novamente com o sublinhado substituído. O problema é que ele apenas substitui um único sublinhado por vez; ele redirectá para um URL mais próximo, mas não muito correto, que redirectá novamente para um URL ainda mais próximo, mas possivelmente ainda não correto …

Ele sugere corrigir vários redirecionamentos tendo várias condições e regras de reescrita com sucessivos mais sublinhados e tokens, mas isso exigiria o mesmo número de condições e regras que você sublinha em seu título mais longo.

Certifique-se de adicionar quaisquer qualificadores, se puder, pois a regra pode replace os caminhos que você não deseja que sejam alterados (por exemplo, arquivos de imagem) como estão.

Como vai rewrite mod saber o que o URL real é suposto ser? Você pode rewrite todos os artigos para usar o sublinhado ou o traço, mas não há como o mod_rewrite dizer se existe novo local.

Por exemplo,

 / I_Like_Bees é armazenado como / path / i_like_bees
 / I-like-flowers é armazenado como / path / i-like-flowers

Você quer que as i-like-bees reescrevam para i_like_bees .

  • Se você rewrite sublinhados em traços, i_like_bees não seria encontrado
  • se você rewrite traços para sublinhar i-like-flowers não seria encontrado

Se você armazenou todos os seus artigos consistentemente, você poderia facilmente fazer um trabalho de regra de reescrita. Em vez disso, você provavelmente terá que escrever um script para verificar a existência de diretórios e fazer um redirecionamento 301 para o local correto.