271 votes

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

Je veux pouvoir convertir des titres qui peuvent contenir n'importe quoi et les débarrasser de tous les caractères spéciaux pour qu'ils ne contiennent que des lettres et des chiffres, et bien sûr remplacer les espaces par des traits d'union.

Comment cela pourrait-il se faire ? J'ai beaucoup entendu parler de l'utilisation d'expressions régulières (regex)...

798voto

Terry Harvey Points 2015

Cela devrait faire ce que vous recherchez :

function clean($string) {
   $string = str_replace(' ', '-', $string); // Replaces all spaces with hyphens.

   return preg_replace('/[^A-Za-z0-9\-]/', '', $string); // Removes special chars.
}

Utilisation :

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

La sortie est prévue : abcdef-g

Editar:

Juste une petite question, comment puis-je empêcher que plusieurs traits d'union se trouvent l'un à côté de l'autre ? et les remplacer par un seul ?

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

0 votes

Il demandait spécifiquement que les espaces soient remplacés par des tirets...

0 votes

@Artaex Media Désolé, j'ai manqué cette partie !

0 votes

7 minutes avant que je puisse le marquer :)

134voto

lserni Points 19089

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

4 votes

Il manque une parenthèse fermante dans le premier bloc de code -->. $str = preg_replace('/[^A-Za-z0-9\. -]/', '', $str);

0 votes

Veuillez mettre à jour votre lien source cleanString()

55voto

Jeffrey Points 653

Tiens, regarde 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, '-'));
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X