Remova todos os caracteres especiais de uma string

Possível Duplicado:
Sanitização de Expressão Regular (PHP)

Eu estou enfrentando um problema com os URLs, quero ser capaz de converter títulos que podem conter qualquer coisa e tê-los despojados de todos os caracteres especiais para que eles apenas tenham letras e números e, claro, gostaria de replace espaços por guias.

Como isso seria feito? Ouvi muito sobre expressões regulares (regex) sendo usadas …

Mole-mole:

function clean($string) { $string = str_replace(' ', '-', $string); // Replaces all spaces with hyphens. return preg_replace('/[^A-Za-z0-9\-]/', '', $string); // Removes special chars. } 

Uso:

 echo clean('a|"bc!@£de^&$f g'); 

Saída do resultado: abcdef-g

Editar:

Ei, apenas uma pergunta rápida, como posso impedir que várias hifens sejam próximas umas das outras? e ter substituído por apenas 1?

 function clean($string) { $string = str_replace(' ', '-', $string); // Replaces all spaces with hyphens. $string = preg_replace('/[^A-Za-z0-9\-]/', '', $string); // Removes special chars. return preg_replace('/-+/', '-', $string); // Replaces multiple hyphens with single one. } 

Atualizar

A solução abaixo tem uma versão “SEO mais amigável”:

 function hyphenize($string) { $dict = array( "I'm" => "I am", "thier" => "their", // Add your own replacements here ); return strtolower( preg_replace( array( '#[\\s-]+#', '#[^A-Za-z0-9\. -]+#' ), array( '-', '' ), // the full cleanString() can be downloaded from http://www.unexpectedit.com/php/php-clean-string-of-utf8-chars-convert-to-similar-ascii-char cleanString( str_replace( // preg_replace can be used to support more complicated replacements array_keys($dict), array_values($dict), urldecode($string) ) ) ) ); } function cleanString($text) { $utf8 = array( '/[áàâãªä]/u' => 'a', '/[ÁÀÂÃÄ]/u' => 'A', '/[ÍÌÎÏ]/u' => 'I', '/[íìîï]/u' => 'i', '/[éèêë]/u' => 'e', '/[ÉÈÊË]/u' => 'E', '/[óòôõºö]/u' => 'o', '/[ÓÒÔÕÖ]/u' => 'O', '/[úùûü]/u' => 'u', '/[ÚÙÛÜ]/u' => 'U', '/ç/' => 'c', '/Ç/' => 'C', '/ñ/' => 'n', '/Ñ/' => 'N', '/–/' => '-', // UTF-8 hyphen to "normal" hyphen '/[''‹›‚]/u' => ' ', // Literally a single quote '/[“”«»„]/u' => ' ', // Double quote '/ /' => ' ', // nonbreaking space (equiv. to 0x160) ); return preg_replace(array_keys($utf8), array_values($utf8), $text); } 

O raciocínio para as funções acima (que eu acho maneira ineficiente – o abaixo é melhor) é que um serviço que não deve ser chamado aparentemente correu verificações ortográficas e reconhecimento de palavras-chave nos URLs.

Depois de perder um longo tempo nas paranóias de um cliente, descobri que eles não estavam imaginando as coisas afinal – seus especialistas em SEO [eu definitivamente não sou um] relataram que, digamos, convertendo “Viaggi Economy Perù” para viaggi-economy-peru ” comportou-se melhor “do que viaggi-economy-per (a anterior” limpeza “removeu caracteres UTF8, Bogotà tornou-se bogot , Medellìn tornou-se medelln e assim por diante).

Havia também alguns erros ortocharts comuns que pareciam influenciar os resultados, e a única explicação que fazia sentido para mim é que nosso URL estava sendo desempacotado, as palavras escolhidas e usadas para dirigir Deus sabe quais algoritmos de sorting. E esses algoritmos aparentemente tinham sido alimentados com cordas limpas com UTF8, de modo que “Perù” se tornou “Peru” em vez de “Per”. “Per” não combinou e tipo de tomou no pescoço.

Para manter os caracteres UTF8 e replace alguns erros ortocharts, a function mais rápida abaixo se tornou a function mais precisa (?) Acima. $dict precisa ser adaptado à mão, é claro.

Resposta anterior

Uma abordagem simples:

 // Remove all characters except AZ, az, 0-9, dots, hyphens and spaces // Note that the hyphen must go last not to be confused with a range (AZ) // and the dot, being special, is escaped with \ $str = preg_replace('/[^A-Za-z0-9\. -]/', '', $str); // Replace sequences of spaces with hyphen $str = preg_replace('/ */', '-', $str); // The above means "a space, followed by a space repeated zero or more times" // (should be equivalent to / +/) // You may also want to try this alternative: $str = preg_replace('/\\s+/', '-', $str); // where \s+ means "zero or more whitespaces" (a space is not necessarily the // same as a whitespace) just to be sure and include everything 

Note que você pode ter que primeiro urldecode() o URL, pois% 20 e + ambos são realmente espaços – quero dizer, se você tiver “Nunca% 20gonna% 20give% 20you% 20up” você quer que ele se torne Never-gonna-give -você-up, não Never20gonna20give20you20up . Você pode não precisar disso, mas pensei que eu mencionaria a possibilidade.

Então, a function terminada juntamente com os casos de teste:

 function hyphenize($string) { return ## strtolower( preg_replace( array('#[\\s-]+#', '#[^A-Za-z0-9\. -]+#'), array('-', ''), ## cleanString( urldecode($string) ## ) ) ## ) ; } print implode("\n", array_map( function($s) { return $s . ' becomes ' . hyphenize($s); }, array( 'Never%20gonna%20give%20you%20up', "I'm not the man I was", "'Légeresse', dit sa majesté", ))); Never%20gonna%20give%20you%20up becomes never-gonna-give-you-up I'm not the man I was becomes im-not-the-man-I-was 'Légeresse', dit sa majesté becomes legeresse-dit-sa-majeste 

Para lidar com UTF-8, usei uma implementação cleanString encontrada aqui . Pode ser simplificado e envolvido dentro da function aqui para desempenho.

A function acima também implementa a conversão em minúsculas – mas isso é um gosto. O código para fazer isso foi comentado.

Aqui, confira esta function:

 function seo_friendly_url($string){ $string = str_replace(array('[\', \']'), '', $string); $string = preg_replace('/\[.*\]/U', '', $string); $string = preg_replace('/&(amp;)?#?[a-z0-9]+;/i', '-', $string); $string = htmlentities($string, ENT_COMPAT, 'utf-8'); $string = preg_replace('/&([az])(acute|uml|circ|grave|ring|cedil|slash|tilde|caron|lig|quot|rsquo);/i', '\\1', $string ); $string = preg_replace(array('/[^a-z0-9]/i', '/[-]+/') , '-', $string); return strtolower(trim($string, '-')); }