Page 1 sur 1

Piqûre de rappel sur les expressions regulières svp

Posté : 14 déc. 2011, 17:54
par foetus69
Bonjour,

Je voulais récupérer le p'tit script des expressions régulières en home mais apparemment il y a du mouvement ^^

du coup je "galère" un peu.

J'ai récupéré ceci pour supprimer accents et espaces.

Code : Tout sélectionner

<?php $fichier = "Exemplé"; echo '<p>'.$fichier.'</p>'; $fichier = strtr($fichier,'ÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÒÓÔÕÖÙÚÛÜÝàáâãäåçèéêëìíîïðòóôõöùúûüýÿ','AAAAAACEEEEIIIIOOOOOUUUUYaaaaaaceeeeiiiioooooouuuuyy'); $fichier = preg_replace('/([^.a-z0-9]+)/i', '-', $fichier); echo '<p>'.$fichier.'</p>'; ?>
Ca marche presque mais au lieu de m'écrire "Exemple" ça m'écrit "Exemply-"

je comprends bien la syntaxe strtr on ne peut plus clair par contre le preg_replace dans l'état :-k et surtout pourquoi ce y- à la place de mon simple e

Avant en iso j'avais pas ce souci...

Merci à vous frères illuminés !!!

Re: Piqûre de rappel sur les expressions regulières svp

Posté : 14 déc. 2011, 18:38
par Calimero
Hello,

Après quelques tests rapides (mise en commentaire de chacune des deux lignes, le tout dans un fichier .php en UTF8), l'expression régulière est responsable de l'ajout du tiret en fin de mot, et le strtr (qui perd les pédales de l'encodage quelquepart) est lui à blâmer pour la transformation du 'é' en 'y' (ce qui déclenche l'expression régulière par ailleurs).

L'expression régulière fait bien ce qu'elle est censée faire, donc si son résultat ne te convient pas il faudra expliquer le résultat voulu et la réécrire en conséquence.

Apparemment, strtr digère mal les caractères UTF-8, en particulier quant il est appelé sous cette forme (3 paramètres : cf les nombreux commentaires à ce sujet sur la page correspondante du manuel php http://fr.php.net/manual/en/function.strtr.php ). Ils suggèrent de passer par un utf8_decode() avant d'appeler strtr.

Le problème ne se pose pas en passant par des appels équivalents à str_replace() en lieu et place :
$fichier=str_replace(array('À','Á','Â','Ã','Ä','Å'),'A',$fichier);
$fichier=str_replace('Ç','C',$fichier);
$fichier=str_replace(array('È','É','Ê','Ë'),'E',$fichier);
$fichier=str_replace(array('Ì','Í','Î','Ï'),'I',$fichier);
$fichier=str_replace(array('Ò','Ó','Ô','Õ','Ö'),'O',$fichier);
$fichier=str_replace(array('Ù','Ú','Û','Ü'),'U',$fichier);
$fichier=str_replace('Ý','Y',$fichier);

$fichier=str_replace(array('àáâãäå',),'a',$fichier);
$fichier=str_replace('ç','c',$fichier);
$fichier=str_replace(array('è','é','ê','ë',),'e',$fichier);
$fichier=str_replace(array('ì','í','î','ï',),'i',$fichier);
$fichier=str_replace(array('ð','ò','ó','ô','õ','ö',),'o',$fichier);
$fichier=str_replace(array('ù','ú','û','ü',),'u',$fichier);
$fichier=str_replace(array('ý','ÿ',),'y',$fichier);

Re: Piqûre de rappel sur les expressions regulières svp

Posté : 14 déc. 2011, 21:46
par foetus69
Bonjour Calimero et merci,

Avant j'utilisais str_replace mais j'ai lu que c'etait un peu has been. Peu être pas finalement :)

Pour le rendu final, je veux juste que les caractères accentués soient non-accentués et que les espaces, simple quotes, guillemets... soient supprimés ou remplacés par des underscores "_" ou des tirets moins "-".

Classique quoi ;)

Tite fée

Re: Piqûre de rappel sur les expressions regulières svp

Posté : 14 déc. 2011, 22:26
par Calimero
Bonjour Calimero et merci,

Avant j'utilisais str_replace mais j'ai lu que c'etait un peu has been. Peu être pas finalement :)
Has-been ? C'est pourtant dans les vieux pots qu'on fait les meilleures soupes :P sérieusement je voudrais bien lire ce que tu as lu, car str_replace() fait à peu près tout et, dans mon expérience, toujours sans surprise (que ce soit pour de l'ascii, de l'utf8, du binaire, même des chiffres, cette fonction fait bien ce qu'on attend d'elle).

Pour le rendu final, je veux juste que les caractères accentués soient non-accentués et que les espaces, simple quotes, guillemets... soient supprimés ou remplacés par des underscores "_" ou des tirets moins "-".

Classique quoi ;)

Tite fée
Normalement le remplacement des caractères accentués se fait bien selon les règles voulues avec les str_replace() que je t'ai copiés pour remplacer le strtr(). Mais certes, c'est moins joli. Rien ne t'empêche de modifier tout ça à ta sauce, de construire par dessus quelquechose de plus élégant, ou d'aborder le problème d'une autre manière qui te conviendrait mieux (par exemple, tu peux diviser la longueur du code par 2 en utilisant str_ireplace). On pourrait aussi aborder la question sous un angle 100% regexp...

Tu peux aussi faire comme décrit dans les commentaires du manuel, et précéder ton strtr d'un utf8_decode() qui fonctionnera tout aussi bien, si tu es ok avec la conversion d'encodage (perso, je préfère éviter autant que possible, on ne sait jamais ce qui peut être perdu ce faisant).

Comme tu dis, c'est du classique... Tellement classique que tu devrais peut-être profiter de l'occasion pour aller chercher une fonction plus éprouvée ailleurs :) Ca peut se trouver dans la plupart des frameworks et CMS, et ça te permettrait de changer un peu de source d'inspiration, et même de comparer des codes de styles différents pour la même fonctionnalité, si le coeur t'en dit.

PS: ta signature est-elle toujours d'actualité, depuis le temps que tu l'as ? 8-|

Re: Piqûre de rappel sur les expressions regulières svp

Posté : 15 déc. 2011, 01:55
par AB
Bonjour Calimero et merci,

Avant j'utilisais str_replace mais j'ai lu que c'etait un peu has been. Peu être pas finalement :)

Tite fée
Je rejoins Calimero, c'est peut-être has been mais c'est le plus sûr et ça fonctionne partout.

Sinon tu peux regarder du côté de iconv ... TRANSLIT mais ça peut poser problème suivant la configuration du serveur.

Bref pourquoi se prendre la tête quand on a une solution fiable ?

J'utilise une fonction assez semblable pour nettoyer les fichiers dans cette class d'upload
Je te recopie la fonction "Nettoie_nom_fichier" de cette classe :
private function Nettoie_nom_fichier($nom_fichier)
{
        $cible = array(
        'À', 'Á', 'Â', 'Ã', 'Ä', 'Å', 'Æ', 'Ă', 'Ą',
        'Ç', 'Ć', 'Č', 'Œ',
        'Ď', 'Đ',
        'à', 'á', 'â', 'ã', 'ä', 'å', 'æ', 'ă', 'ą',
        'ç', 'ć', 'č', 'œ',
        'ď', 'đ',
        'È', 'É', 'Ê', 'Ë', 'Ę', 'Ě',
        'Ğ',
        'Ì', 'Í', 'Î', 'Ï', 'İ',
        'Ĺ', 'Ľ', 'Ł',
        'è', 'é', 'ê', 'ë', 'ę', 'ě',
        'ğ',
        'ì', 'í', 'î', 'ï', 'ı',
        'ĺ', 'ľ', 'ł',
        'Ñ', 'Ń', 'Ň',
        'Ò', 'Ó', 'Ô', 'Õ', 'Ö', 'Ø', 'Ő',
        'Ŕ', 'Ř',
        'Ś', 'Ş', 'Š',
        'ñ', 'ń', 'ň',
        'ò', 'ó', 'ô', 'ö', 'ø', 'ő',
        'ŕ', 'ř',
        'ś', 'ş', 'š',
        'Ţ', 'Ť',
        'Ù', 'Ú', 'Û', 'Ų', 'Ü', 'Ů', 'Ű',
        'Ý', 'ß',
        'Ź', 'Ż', 'Ž',
        'ţ', 'ť',
        'ù', 'ú', 'û', 'ų', 'ü', 'ů', 'ű',
        'ý', 'ÿ',
        'ź', 'ż', 'ž',
        'А', 'Б', 'В', 'Г', 'Д', 'Е', 'Ё', 'Ж', 'З', 'И', 'Й', 'К', 'Л', 'М', 'Н', 'О', 'П', 'Р',
        'а', 'б', 'в', 'г', 'д', 'е', 'ё', 'ж', 'з', 'и', 'й', 'к', 'л', 'м', 'н', 'о', 'р',
        'С', 'Т', 'У', 'Ф', 'Х', 'Ц', 'Ч', 'Ш', 'Щ', 'Ъ', 'Ы', 'Ь', 'Э', 'Ю', 'Я',
        'с', 'т', 'у', 'ф', 'х', 'ц', 'ч', 'ш', 'щ', 'ъ', 'ы', 'ь', 'э', 'ю', 'я'
        );
                                 
        $rempl = array(
        'A', 'A', 'A', 'A', 'A', 'A', 'AE', 'A', 'A',
        'C', 'C', 'C', 'CE',
        'D', 'D',
        'a', 'a', 'a', 'a', 'a', 'a', 'ae', 'a', 'a',
        'c', 'c', 'c', 'ce',
        'd', 'd',
        'E', 'E', 'E', 'E', 'E', 'E',
        'G',
        'I', 'I', 'I', 'I', 'I',
        'L', 'L', 'L',
        'e', 'e', 'e', 'e', 'e', 'e',
        'g',
        'i', 'i', 'i', 'i', 'i',
        'l', 'l', 'l',
        'N', 'N', 'N',
        'O', 'O', 'O', 'O', 'O', 'O', 'O',
        'R', 'R',
        'S', 'S', 'S',
        'n', 'n', 'n',
        'o', 'o', 'o', 'o', 'o', 'o',
        'r', 'r',
        's', 's', 's',
        'T', 'T',
        'U', 'U', 'U', 'U', 'U', 'U', 'U',
        'Y', 'Y',
        'Z', 'Z', 'Z',
        't', 't',
        'u', 'u', 'u', 'u', 'u', 'u', 'u',
        'y', 'y',
        'z', 'z', 'z',
        'A', 'B', 'B', 'r', 'A', 'E', 'E', 'X', '3', 'N', 'N', 'K', 'N', 'M', 'H', 'O', 'N', 'P',
        'a', 'b', 'b', 'r', 'a', 'e', 'e', 'x', '3', 'n', 'n', 'k', 'n', 'm', 'h', 'o', 'p',
        'C', 'T', 'Y', 'O', 'X', 'U', 'u', 'W', 'W', 'b', 'b', 'b', 'E', 'O', 'R',
        'c', 't', 'y', 'o', 'x', 'u', 'u', 'w', 'w', 'b', 'b', 'b', 'e', 'o', 'r'
        );
                 
        $nom_fichier = str_replace($cible, $rempl, $nom_fichier);

        $nom_fichier = preg_replace('#[^.a-z0-9_-]+#i', '', $nom_fichier);
                                                 
        if (trim($nom_fichier) != '')
                                                 
        return $nom_fichier;
        else
        return false;
}
Pour faire un peu la même chose j'utilisais "iconv" mais j'ai dû revenir à cette bonne vielle méthode suite à cette observation.

Re: Piqûre de rappel sur les expressions regulières svp

Posté : 19 déc. 2011, 17:59
par foetus69
Bonjour,

MERCI A TOUS (encore une fois)

Bonnes fêtes de fin d'année !!! (si je reviens pas d'ici là :roll:)

Re: Piqûre de rappel sur les expressions regulières svp

Posté : 19 déc. 2011, 20:02
par AB
Bonnes fêtes à toi aussi :)

J'ai oublié de dire au passage que quand iconv fonctionne correctement il remplace moins de caractères que ceux qui sont dans le tableau. La solution du str_replace peut donc en faire plus et au choix (on peut toujours rajouter des caractères en correspondance).

En fait la solution iconv n'est vraiment utile que quand on veut faire des sites multi-langue avec des langues qui utilisent des caractères non listés dans le str_replace (on pourrait toujours faire un tableau de correspondance pour chaque langue mais ce serait assez laborieux).