Mise à jour
La solution ci-dessous a une version "SEO friendly" :
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);
}
La raison d'être des fonctions ci-dessus (que je trouve chemin inefficace - celle ci-dessous est meilleure) est que un service qui ne doit pas être nommé a apparemment vérifié l'orthographe et la reconnaissance des mots-clés sur les URL.
Après avoir perdu beaucoup de temps sur les paranoïas d'un client, j'ai découvert qu'elles étaient no d'imaginer des choses après tout -- leurs experts en référencement [je n'en suis absolument pas un] ont signalé que, par exemple, la conversion de "Viaggi Economy Perù" en viaggi-economy-peru
"s'est mieux comporté" que viaggi-economy-per
(le "nettoyage" précédent a supprimé les caractères UTF8 ; Bogotà est devenu bogot , Medellìn est devenu medelln et ainsi de suite).
Certaines fautes d'orthographe courantes semblaient également influencer les résultats, et la seule explication qui me paraissait logique était que notre URL était décortiquée, les mots isolés et utilisés pour piloter Dieu sait quels algorithmes de classement. Et ces algorithmes avaient apparemment été alimentés avec des chaînes nettoyées en UTF8, de sorte que "Perù" devenait "Peru" au lieu de "Per". "Per" ne correspondait pas et l'a en quelque sorte pris dans le cou.
Afin de conserver les caractères UTF8 et de remplacer certaines fautes d'orthographe, la fonction rapide ci-dessous est devenue la fonction plus précise ( ?) ci-dessus. $dict
doit être adapté à la main, bien sûr.
Réponse précédente
Une approche simple :
// Remove all characters except A-Z, a-z, 0-9, dots, hyphens and spaces
// Note that the hyphen must go last not to be confused with a range (A-Z)
// and the dot, NOT being special (I know. My life was a lie), is NOT escaped
$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
Notez que vous devrez peut-être d'abord urldecode()
l'URL, puisque %20 et + sont en fait des espaces - je veux dire que si vous avez "Never%20gonna%20give%20you%20up", vous voulez que cela devienne Never-gonna-give-you-up, pas Never20gonna20give20you20up . Vous n'en aurez peut-être pas besoin, mais je pensais mentionner cette possibilité.
Donc la fonction finie avec les cas de test :
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
Pour gérer UTF-8, j'ai utilisé un cleanString
qui convertit les caractères UTF8 en caractères normaux, préservant ainsi autant que possible l'aspect du mot. Elle pourrait être simplifiée et intégrée à la fonction présentée ici pour des raisons de performances.
La fonction ci-dessus implémente également la conversion en minuscules - mais c'est un avant-goût. Le code pour le faire a été commenté.