IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage PHP Discussion :

Nettoyer une chaîne de caractères


Sujet :

Langage PHP

  1. #1
    Membre régulier
    Homme Profil pro
    HobbyWeb
    Inscrit en
    Janvier 2005
    Messages
    183
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : Suisse

    Informations professionnelles :
    Activité : HobbyWeb

    Informations forums :
    Inscription : Janvier 2005
    Messages : 183
    Points : 102
    Points
    102
    Par défaut Nettoyer une chaîne de caractères
    Bonjour,

    J'essaye de nettoyer une chaîne, tout ce qui à moins de deux caractère out... par contre et je sais pas pourquoi, il ne tient pas compte de tous les mots de moins de deux caractères comme des à, â où, etc...
    Par contre, je ne souhaite pas qu'un mot du genre âgé se voit amputé du â

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    $keywordsy = "à la gare de düsseldorf en allemagne, c'est pas là !";
     
    // Nettoyer la chaine
    while(preg_match("# ([[:alnum:]]{1,2}) #", $keywordsy))
    $keywordsy =  preg_replace("#( [[:alnum:]]{1,2} )#iu", " ", $keywordsy);
     
    echo $keywordsy;
    Il m'affiche ceci : à gare düsseldorf allemagne, c'est pas !

    Alors que j'aimerais ceci : gare düsseldorf allemagne, est pas !

    Pourquoi le à n'est pas supprimé et ni le c' ?

    Comment corriger pour y arriver ?

    D'avance merci
    Yule

  2. #2
    Membre émérite
    Avatar de badaze
    Homme Profil pro
    Chef de projets info
    Inscrit en
    Septembre 2002
    Messages
    1 412
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets info
    Secteur : Transports

    Informations forums :
    Inscription : Septembre 2002
    Messages : 1 412
    Points : 2 522
    Points
    2 522
    Par défaut
    Essaie ça. C'est sûrement optimisable (je ne suis pas un Dieu en regexp)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    <?php
    $keywordsy = "à la gare de düsseldorf en allemagne, c'est pas là dell'aquila. Tu l'as dit bouffi ! Oui je l'avais dit";
    print "$keywordsy<br/>";
    $caractères  = "[a-z0-9àáâãäåçèéêëìíîïðòóôõöùúûüýÿA-ZÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÐÒÓÔÕÖÙÚÛÜÝŸ]";
    $caractères2 = "[a-z0-9àáâãäåçèéêëìíîïðòóôõöùúûüýÿA-ZÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÐÒÓÔÕÖÙÚÛÜÝŸ\s]";
    //======  Suppression des mots : pas précédé par un caractère suivi de 1 ou 2 caractères pas suivi par un caractère
    $keywordsy   =  preg_replace("#(?<!$caractères)($caractères{1,2})(?!$caractères)#ium", " ", $keywordsy);
    //======  Suppression des apostrophes : pas précédé par un caractère suivi d'une apostrohe suivie par un caractère2
    $keywordsy   =  preg_replace("#(?<!$caractères)(\')(?=$caractères2)#ium", " ", $keywordsy);
    echo $keywordsy;
    Cela ne sert à rien d'optimiser quelque chose qui ne fonctionne pas.

    Mon site : www.emmella.fr

    Je recherche le manuel de l'Olivetti Logos 80B.

  3. #3
    Membre émérite
    Avatar de badaze
    Homme Profil pro
    Chef de projets info
    Inscrit en
    Septembre 2002
    Messages
    1 412
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets info
    Secteur : Transports

    Informations forums :
    Inscription : Septembre 2002
    Messages : 1 412
    Points : 2 522
    Points
    2 522
    Par défaut
    Attention le code dans Visualiser dans une fenêtre à part n'est pas le même que celui dans le fil.


    Visualiser dans une fenêtre à part :

    Nom : 170315-001.JPG
Affichages : 316
Taille : 55,8 Ko


    Code dans la discussion :

    Nom : 170315-002.JPG
Affichages : 354
Taille : 54,4 Ko
    Cela ne sert à rien d'optimiser quelque chose qui ne fonctionne pas.

    Mon site : www.emmella.fr

    Je recherche le manuel de l'Olivetti Logos 80B.

  4. #4
    Invité
    Invité(e)
    Par défaut
    Bonjour,

    Tu confonds nombre de caractères et nombre d'octets (nécessaires par caractère).
    En l'occurrence, les caractères accentués sont sur plusieurs octets.

    Il faut utiliser les Fonctions sur les chaînes de caractères multi-octets

  5. #5
    Membre émérite
    Avatar de badaze
    Homme Profil pro
    Chef de projets info
    Inscrit en
    Septembre 2002
    Messages
    1 412
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets info
    Secteur : Transports

    Informations forums :
    Inscription : Septembre 2002
    Messages : 1 412
    Points : 2 522
    Points
    2 522
    Par défaut
    A qui réponds-tu ? Si c'est à moi, je voulais seulement indiquer une différence dans le rendu du code.

    Pour ce qui est des caractères accentués, le code que j'ai posté fonctionne bien avec.


    à la gare de düsseldorf en allemagne, c'est pas là dell'aquila. Tu l'as dit bouffi ! Oui je l'avais dit âgé ÙÚ ÙÚÙ
    donne

    gare düsseldorf allemagne, est pas dell'aquila. dit bouffi ! Oui avais dit âgé ÙÚÙ
    Cela ne sert à rien d'optimiser quelque chose qui ne fonctionne pas.

    Mon site : www.emmella.fr

    Je recherche le manuel de l'Olivetti Logos 80B.

  6. #6
    Invité
    Invité(e)
    Par défaut
    Je répondais et expliquais le pourquoi de ça :
    Pourquoi le à n'est pas supprimé ?
    Tant à ton code (pas testé), il ne prend pas en compte TOUS les caractères multi-octets (cyrilliques, asiatiques,...).

    Les fonctions dont je parle, si.

  7. #7
    Expert éminent Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 885
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Justicier interdimensionnel

    Informations forums :
    Inscription : Mars 2009
    Messages : 2 885
    Points : 6 619
    Points
    6 619
    Par défaut
    Le "à" n'est pas supprimé parce qu'il est début de chaîne et qu'il n'y a pas d'espace avant donc la pattern échoue. Quand bien même il y aurait un espace avant ce "à", ça ne résoudrait rien car dans ce cas se serait le "la" qui serait zappé (vu que l'espace précédent aurait déjà été consommé).

    Pour ce qui est du fait que les caractères accentués sont codés (en UTF-8) sur plusieurs octets, ce n'est pas un problème dés lors qu'on utilise le modificateur u, car dans ce cas le moteur de regex lit bien la chaîne sujet et la pattern en UTF-8 comme des successions de caractères éventuellement sur plusieurs octets; avec ce modificateur, il n'a plus son comportement par défaut (un octet = un caractère) et son unité devient le point unicode.

    À ce stade, on pourrait écrire une de ces lignes équivalentes:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $str = preg_replace('~(?<![[:alnum:]])[[:alnum:]]{1,2}(?![[:alnum:]])~u', '', $str);
    $str = preg_replace('~(?<!\p{Xan})\p{Xan}{1,2}(?!\p{Xan})~u', '', $str);
    Ce qui fonctionnera dans 95% des cas, il ne reste plus qu'a supprimer les espaces consécutifs si nécessaire.

    Mais il reste bien 5% tapi dans les buissons et qui attend son heure: Le caractère combinant.
    Une lettre accentuée peut être formée de deux manières avec unicode. Par exemple un À peut être soit le point unicode U+00C0 (LATIN CAPITAL LETTER A WITH GRAVE), soit la combinaison des points unicode U+0041 (LATIN CAPITAL LETTER A) et U+0300 (COMBINING GRAVE ACCENT). Et si je fait un petit test:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    var_dump(preg_match('~^\p{Xan}$~u', "\xC3\x80")); // U+00C0 (LATIN CAPITAL LETTER A WITH GRAVE)
    // int(1)
    var_dump(preg_match('~^\p{Xan}$~u', "\x41\xCC\x80")); // U+0041 (LATIN CAPITAL LETTER A) + U+0300 (COMBINING GRAVE ACCENT)
    // int(0)
    on voit bien que la version combinée échoue.

    La classe de caractère unicode M (Mark) contient les caractères combinant. Donc pour représenter une lettre accentuée ou pas, il faudrait écrire: \pL\pM*. Ce qui change la pattern en:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $str = preg_replace('~(?<![\p{Xan}\pM])(?>\pL\pM*|\d){1,2}(?![\p{Xan}\pM])~u', '', $str);
    Brachygobius xanthozonus
    Ctenobrycon Gymnocorymbus

  8. #8
    Expert éminent Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 885
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Justicier interdimensionnel

    Informations forums :
    Inscription : Mars 2009
    Messages : 2 885
    Points : 6 619
    Points
    6 619
    Par défaut
    Écrire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    while ( preg_match($pattern, $str) ) { 
        $str = preg_replace($pattern, $replacement, $str);
    }
    c'est le mal à l'état pur.

    Si on a besoin de faire plusieurs passes pour une même pattern, au lieu de la tester 2 fois à chaque tour de boucle, il faut plutôt utiliser le 5e paramètre de preg_replace qui comptabilise le nombre de remplacements effectués en faisant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    do {
        $str = preg_replace($pattern, $replacement, $str, -1, $count);
    } while ($count);
    Mais pour la pattern précédente, c'est inutile, une seule passe suffit.
    Brachygobius xanthozonus
    Ctenobrycon Gymnocorymbus

  9. #9
    Membre régulier
    Homme Profil pro
    HobbyWeb
    Inscrit en
    Janvier 2005
    Messages
    183
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : Suisse

    Informations professionnelles :
    Activité : HobbyWeb

    Informations forums :
    Inscription : Janvier 2005
    Messages : 183
    Points : 102
    Points
    102
    Par défaut
    Hello,

    Merci à vous tous pour votre aide.

    J'ai essayé en live et c'est pas terrible.., je dois mal adapter vos solutions.


    Voilà la fonction que j'utilise (surligner les mots trouvés et afficher le texte (ou le mot clef se trouve par tranche de 70 caractères), pour le coup, pas de surlignage et mon texte sorte n'importe comment)


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    <?php
    		$keywordsy ="la mort en directe fascine les gens à":
     
    		function get_snippet($keywordsy, $texte) {
    		$snippet='';
    		$span = 70;
    		$strlen_max = 400;
     
    		$keywordsy = preg_replace("#(?<![\p{Xan}\pM])(?>\pL\pM*|\d){1,2}(?![\p{Xan}\pM])#U", " ", " ".$keywordsy." ");
     
    		$words = join('|', explode(' ', preg_quote($keywordsy)));
     
    		preg_match_all("#(\W.{0,$span}\W)($words)(\W.{0,$span}\W)#iu", "  $texte  ", $matches);
     
    		foreach($matches[0] as $match) {
    		if (!$match = trim($match)) continue;
    		if (isset($snippet)) $snippet .= "$match..."; else $snippet = "...$match...";
    		if (strlen($snippet.htmlspecialchars($match[0], 'UTF-8')."... ") > $strlen_max) break;
    		}
    		$snippet = preg_replace("#($words)#iu", '<b>$1</b>', $snippet);
    		return $snippet;
      		}
     
    		?>
    20 minutes - vous allez en parler de fr it index de a à z actualitésvaudgenèveromandiesuissemondefaits diversinsolitescience et natureeconomienewsboursepostfinance newspromo
    sportsfootballhockeytenniscyclismeauto & motosports d'hiverautres sportspeoplel'actu des starsnews tvdossiershi-techactualitésvidéosgamezonelifestyletendancesautohoroscope ..

    Avec mon ancienne fonction (pas optimale pour un rond) que j'aimerais changer..

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    <?php
    		$keywordsy ="la mort en directe fascine les gens à":
     
    		function get_snippet($keywordsy, $texte) {
    		$snippet='';
    		$span = 70;
    		$strlen_max = 400;
     
    		$keywordsy =  trim(preg_replace("#( [[:alnum:]]{1,2} )#Ui", " ", " ".$keywordsy." ")); // ajout d'un espace avant et 
     
    		// supprimer ceux à deux  
    		$keywordsy = str_replace(' un ',' ',$keywordsy);
    		$keywordsy = str_replace(' une ',' ',$keywordsy);
    	        $keywordsy = str_replace(' dans ',' ',$keywordsy);
    		$keywordsy = str_replace(' le ',' ',$keywordsy);
    	        $keywordsy = str_replace(' de ',' ',$keywordsy);
    	        $keywordsy = str_replace(' des ',' ',$keywordsy);
    		$keywordsy = str_replace(' les ',' ',$keywordsy);
    	        $keywordsy = str_replace(' ses ',' ',$keywordsy);
    		$keywordsy = str_replace(' se ',' ',$keywordsy);
    		// etc........
    		$keywordsy = trim($keywordsy);
     
    		$words = join('|', explode(' ', preg_quote($keywordsy)));
     
    		preg_match_all("#(\W.{0,$span}\W)($words)(\W.{0,$span}\W)#iu", "  $texte  ", $matches);
     
    		foreach($matches[0] as $match) {
    		if (!$match = trim($match)) continue;
    		if (isset($snippet)) $snippet .= "$match..."; else $snippet = "...$match...";
    		if (strlen($snippet.htmlspecialchars($match[0], 'UTF-8')."... ") > $strlen_max) break;
    		}
    		$snippet = preg_replace("#($words)#iu", '<b>$1</b>', $snippet);
    		return $snippet;
      		}
    		?>
    J'ai ce résultat avec une mise en forme du texte affichée correct (par contre j'aurais le à surligné..

    20 minutes card genève paie de 1750 fr. par mois pour la secrétaire à 100% jérôme faas - l’annonce pour ce cdi est apparue sur le site jobup....de sa propre fille en la trollant une adolescente de miami a mis fin à ses jours en direct sur facebook, encouragée par des internautes qui l'.... parmi eux, la propre mère de la victime. réseaux sociaux: la mort en direct fascine les gens la vidéo de sa mort fait le buzz, la police est...
    D'avance merci de me dire ce que je fais de faux..
    Bonne bonne
    Yule

  10. #10
    Membre émérite
    Avatar de badaze
    Homme Profil pro
    Chef de projets info
    Inscrit en
    Septembre 2002
    Messages
    1 412
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets info
    Secteur : Transports

    Informations forums :
    Inscription : Septembre 2002
    Messages : 1 412
    Points : 2 522
    Points
    2 522
    Par défaut
    Tu dois faire quoi au juste ?
    Cela ne sert à rien d'optimiser quelque chose qui ne fonctionne pas.

    Mon site : www.emmella.fr

    Je recherche le manuel de l'Olivetti Logos 80B.

  11. #11
    Membre régulier
    Homme Profil pro
    HobbyWeb
    Inscrit en
    Janvier 2005
    Messages
    183
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : Suisse

    Informations professionnelles :
    Activité : HobbyWeb

    Informations forums :
    Inscription : Janvier 2005
    Messages : 183
    Points : 102
    Points
    102
    Par défaut
    Hello,

    Une fonction qui me permet d'afficher 70 caractères dès un ou plusieurs mots clés trouvé dans un texte de plus de 1000 caractères.

    Et pour éviter d'avoir des phrases de 70 caractères qu'avec des et ou des est ou de etc... surligné j'aimerais supprimer tous les mots de moins de 3 caractères afin d'avoir en surlignage que des termes d'au moins 4 caractères

    Par l'exemple...

    disons que je cherche : un diamant exceptionnel trouvé par un pasteur

    C'est mieux d'avoir ce résultat dans ma recherche
    avec les stéréotypes dominants et qui ont accompli quelque chose d’exceptionnel.12 000 autres bourses d’études, pour que chacun ait sa chance : http://...

    Que celui-ci
    de cap pour trouver le bon chemin avec une subvention complète pour un cours de langue de 4 semaines à san diego aux États-unis : http://www.... ! », des étudiants peuvent s’envoler vers les États-unis ou vers un pays européen pour y suivre des cours de langue – le vol, l’...avec les stéréotypes dominants et qui ont accompli quelque chose d’exceptionnel.12 000 autres bourses d’études, pour que chacun ait sa chance :
    Je sais plus si je l'ai dit, c'est pour un moteur de recherche (voir signature)

  12. #12
    Membre régulier
    Homme Profil pro
    HobbyWeb
    Inscrit en
    Janvier 2005
    Messages
    183
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : Suisse

    Informations professionnelles :
    Activité : HobbyWeb

    Informations forums :
    Inscription : Janvier 2005
    Messages : 183
    Points : 102
    Points
    102
    Par défaut
    re,

    C'est tout bon , j'ai enfin trouvé une solution de contournement de mon expression (https://regex101.com/r/yP0hI0/1) pour supprimer tous les mots de 3 caractères à moins....

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    function RemoveLess($String,$Char=3) 
    		{
    			$StringArray=explode (" ",$String);
    				foreach ($StringArray as &$Word) 
    				{
    					if (mb_strlen($Word,"UTF-8")>$Char)
    					{ 
    						$Str.=$Word." ";
    					}
    				}
    			return trim($Str);
    		}

Discussions similaires

  1. [Turbo Pascal] Fonction qui permet de nettoyer une chaîne de caractères
    Par med.ycf dans le forum Turbo Pascal
    Réponses: 6
    Dernier message: 05/03/2014, 23h11
  2. Réponses: 8
    Dernier message: 12/02/2013, 01h08
  3. [Debutant(e)] Analyse d'une chaîne de caractères
    Par maire106 dans le forum Langage
    Réponses: 6
    Dernier message: 22/03/2004, 15h04
  4. Inverser une chaîne de caractères
    Par DBBB dans le forum Assembleur
    Réponses: 2
    Dernier message: 30/03/2003, 11h09
  5. Réponses: 3
    Dernier message: 09/05/2002, 01h39

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo