Duplicate possible:
Sanitize Expression régulière (PHP)
Je suis confronté à un problème d'URL. Je veux pouvoir convertir des titres pouvant contenir quoi que ce soit et les supprimer de tous les caractères spéciaux afin qu'ils ne contiennent que des lettres et des chiffres. Bien sûr, j'aimerais remplacer les espaces par des tirets.
Comment cela serait-il fait? J'ai beaucoup entendu parler des expressions régulières (regex) utilisées ...
Peasy facile:
function clean($string) {
$string = str_replace(' ', '-', $string); // Replaces all spaces with hyphens.
return preg_replace('/[^A-Za-z0-9\-]/', '', $string); // Removes special chars.
}
Usage:
echo clean('a|"bc!@£de^&$f g');
Sortie: abcdef-g
Modifier:
Hé, juste une petite question, comment puis-je empêcher plusieurs traits d'union d'être côte à côte? et les ont remplacés par seulement 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.
}
La solution ci-dessous a une version "SEO friendlylier":
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 justification des fonctions ci-dessus (que je trouve comme inefficace - celle ci-dessous est meilleure) est la suivante un service qui ne doit pas être nommé a apparemment exécuté des vérifications orthographiques et des mots clés sur les URL.
Après avoir perdu beaucoup de temps sur les paranoias d'un client, j'ai découvert qu'ils n'étaient pas en train d'imaginer des choses - leurs experts en référencement [je n'en suis certainement pas un] a rapporté que, par exemple, la conversion de "Viaggi Economy Perù" en viaggi-economy-peru
"se comportait mieux" que viaggi-economy-per
(l'ancien "nettoyage" supprimait les caractères UTF8; Bogotà est devenu bogot, Medellìn est devenu medelln et ainsi de suite).
Certaines fautes d'orthographe courantes semblaient avoir une influence sur les résultats, et la seule explication qui me paraissait logique est que notre URL était décompressée, les mots isolés et utilisés pour conduire Dieu sait quels algorithmes de classement. Et ces algorithmes avaient apparemment été alimentés avec des chaînes nettoyées par UTF8, de sorte que "Perù" devienne "Pérou" au lieu de "Per". "Per" ne correspond pas et en quelque sorte l'a pris dans le cou.
Afin de conserver les caractères UTF8 et de remplacer certaines fautes d'orthographe, la fonction la plus rapide ci-dessous devient la fonction plus précise (?) Ci-dessus. $dict
doit être adapté à la main, bien sûr.
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, 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
Notez que vous devrez peut-être d'abord urldecode()
l'URL, puisque% 20 et + sont en fait des espaces - je veux dire, si vous avez "Jamais% 20gonna% 20give% 20you% 20yup", vous voulez que cela devienne jamais. -Give-You-Up, pas Never20gonna20give20you20up . Vous n'en aurez peut-être pas besoin, mais je pensais mentionner la possibilité.
Donc, la fonction terminée 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é une implémentation cleanString
trouvée en ligne (lien rompu depuis, mais une copie simplifiée comportant tous les caractères UTF8 qui ne sont pas trop ésotériques est au début de la réponse; il est également facile d’en ajouter de nouveaux si vous avez besoin) qui convertit les caractères UTF8 en caractères normaux, préservant ainsi le "look" du mot autant que possible. Il pourrait être simplifié et intégré à la fonction pour plus de performance.
La fonction ci-dessus implémente également la conversion en minuscule - mais c'est un goût. Le code pour le faire a été commenté.
Ici, vérifiez cette fonction:
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('/&([a-z])(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, '-'));
}