web-dev-qa-db-fra.com

Supprimer tous les caractères spéciaux d'une chaîne

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 ...

191
user115422

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.
}
603
Terry Harvey

Mise à jour

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.

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, 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é.

98
LSerni

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, '-'));
}
35
Jeffrey