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 :

Manipulation de chaine de caractères [RegEx]


Sujet :

Langage PHP

  1. #1
    Membre à l'essai
    Femme Profil pro
    Développeur Web
    Inscrit en
    Mai 2014
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 49
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Mai 2014
    Messages : 24
    Points : 16
    Points
    16
    Par défaut Manipulation de chaine de caractères
    Bonjour à tous,

    et merci de votre aide !

    je rencontre un souci de syntaxe dans les expressions régulières...

    je suis en train de créer un moteur de recherche dans mon site,
    j'ai le champ "contenu" de ma table - $dnn['descriptif']
    et le mot ou l'expression recherchée - $rec

    je souhaite afficher uniquement la chaine de caractère contenant les 10 mots précédents ma recherche, la recherche, et les 10 mots suivants.

    j'ai cherché du coté des fonctions ereg() et eregi() mais je ne sais pas bien comment rédiger ma syntaxe avec les tutos que j'ai trouvé.
    après quelques essais infructueux, j'ai ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $chaine=eregi($rec,$dnn['descriptif'],$reg);
    echo $reg[0];
    qui n'affiche que le mot recherché.

    comment m'y prendre ?

    En vous remerciant de votre aide...

  2. #2
    Membre expert
    Avatar de Spartacusply
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mai 2011
    Messages
    1 723
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mai 2011
    Messages : 1 723
    Points : 3 274
    Points
    3 274
    Par défaut
    Ne jamais sous-estimer les tableaux php :

    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
    37
    38
    39
    40
    41
    42
    43
    44
    <?php
     
    function search($wordSearch, $text, $nbWords = 10) {
     
        //On enlève la ponctuation pour la recherche
        $carToReplace = array('.', ',', '?', '!', ':', ';', '"', '...', '(', ')', "'");
     
        $textToSearch = str_replace($carToReplace, "", $text);
     
        $tabTextToSearch = explode(" ", $textToSearch);
        $tabText = explode(" ", $text);
     
        $resSearch = array_search($wordSearch, $tabTextToSearch);
        if ($resSearch === false) {
            return false;
        }
     
        $indexFirstWord = $resSearch - $nbWords;
        if ($indexFirstWord < 0) {
            $indexFirstWord = 0;
        }
     
        $before = array_slice($tabText, $indexFirstWord, $nbWords);
        $after = array_slice($tabText, $resSearch + 1, $nbWords);
     
        return array(
            'before' => implode(' ', $before),
            'word' => $wordSearch,
            'after' => implode(' ', $after),
        );
    }
     
    $text = "Voici un texte de texte, dans lequel on va chercher un mot en particulier et qui affichera (ceci est un test) les '10 mots' qui se situe avant "
            . "et après ce mot, pour voir comment c'est facile d'utiliser les tableaux en php.";
     
    $wordSearch = "particulier";
     
    $resSearch = search($wordSearch, $text);
     
    if ($resSearch !== false) {
        print_r($resSearch);
    } else {
        echo "Mot non trouvé dans la chaîne";
    }
    Cette fonction est adaptable en fonction de ce que tu souhaites faire exactement (actuellement c'est une recherche la plus stricte possible qui est applquée).

    Une remarque au passage, les fonction de type "ereg" sont dépréciées depuis Php 5.3, privilégier l'utilisation des fonction "preg_..." à la place.
    Un message utile vous a aidé ? N'oubliez pas le

    www.simplifions.fr - Simplifier vos comptes entre amis !

  3. #3
    Membre à l'essai
    Femme Profil pro
    Développeur Web
    Inscrit en
    Mai 2014
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 49
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Mai 2014
    Messages : 24
    Points : 16
    Points
    16
    Par défaut Merci !!
    merci Spartacusply

    Cette fonction est intéressante, je m'y suis appuyée.
    j'ai fait une modification pour rendre l'affichage plus agréable.
    au lieu d'avoir les array et [0] etc. ça s'affiche simplement, avec le mot en gras. voici le code modifié :
    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
    37
    38
    39
    40
    41
    42
    43
    44
    <?php
     
    function search($wordSearch, $text, $nbWords = 10) {
     
        //On enlève la ponctuation pour la recherche
        $carToReplace = array('.', ',', '?', '!', ':', ';', '"', '...', '(', ')', "'");
     
        $textToSearch = str_replace($carToReplace, "", $text);
     
        $tabTextToSearch = explode(" ", $textToSearch);
        $tabText = explode(" ", $text);
     
        $resSearch = array_search($wordSearch, $tabTextToSearch);
        if ($resSearch === false) {
            return false;
        }
     
        $indexFirstWord = $resSearch - $nbWords;
        if ($indexFirstWord < 0) {
            $indexFirstWord = 0;
        }
     
        $before = array_slice($tabText, $indexFirstWord, $nbWords);
        $after = array_slice($tabText, $resSearch + 1, $nbWords);
     
        return array(
            implode(' ', $before),
            '<strong>'.$wordSearch.'</strong>',
            implode(' ', $after),
        );
    }
     
    $text = "Voici un texte de texte, dans lequel on va chercher un mot en particulier et qui affichera (ceci est un test) les '10 mots' qui se situe avant et après ce mot, pour voir comment c'est facile d'utiliser les tableaux en php.";
     
    $wordSearch = "mot";
     
    $resSearch = search($wordSearch, $text);
     
    if ($resSearch !== false) {
        echo implode(" ",$resSearch);
    } else {
        echo "Mot non trouvé dans la chaîne";
    }
    ?>
    le résultat de ce test est :
    un texte de texte, dans lequel on va chercher un mot en particulier et qui affichera (ceci est un test) les

    j'ai par contre remarqué un souci qui est aussi présent dans ta version, et qui me semble un peut gênant :
    lorsqu'il y a moins de 10 mots avant le mot recherché, il affiche 10 mots (dont le mot recherché), puis il affiche la suite, dont une partie est donc en doublon.
    exemple :
    avec le mot "lequel" en recherche, j'ai ceci :
    "Voici un texte de texte, dans lequel on va chercher lequel on va chercher un mot en particulier et qui affichera"
    doublon de "lequel on va chercher"


    je vais essayer d'améliorer ça, et je reviens.
    de même je vais protéger les accents.

    à plus tard !

  4. #4
    Expert éminent Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 858
    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 858
    Points : 6 556
    Points
    6 556
    Par défaut
    Déjà il faut définir ce qu'est un mot. Pour l'exemple, je choisi qu'un mot est un ensemble de caractère composé uniquement de chiffres et de lettres, et délimité par des caractères n'étant pas un chiffre ou une lettre, ou par les limites de la chaîne.

    Donc il faut trouver une classe de caractère qui correspond à cette définition. La classe \p{Xan} contient les chiffres et lettres de tous les alphabets contenus dans les tables unicode. \P{Xan} correspond à son contraire.

    Pour résoudre le problème des limites de la chaîne (il n'y a pas forcément 10 mots entre le début de la chaîne et l'expression recherchée), il suffit d'utiliser {0,10} comme quantificateur, en prenant soin de le rendre non-gourmand {0,10}? pour qu'il s'arrête avant l'expression recherchée et qu'il ne l'englobe pas.

    On aboutit alors au pattern:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    (?:\p{Xan}+\P{Xan}+){0,10}?expression(?:\P{Xan}+\p{Xan}+){0,10}
    Exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    function getExcerpt($needle, $str) {
        $pattern = '~((?:\p{Xan}+\P{Xan}+){0,10}?)(' . preg_quote($needle, '~') . ')((?:\P{Xan}+\p{Xan}+){0,10})~i';    
        if (preg_match($pattern, $str, $match)) 
            return $match[1] . '<strong>' . $match[2] . '</strong>' . $match[3];
        else
            return false;
    }
    Tu peux aussi te limiter aux lettres en utilisant \p{L} et \P{L}.
    Brachygobius xanthozonus
    Ctenobrycon Gymnocorymbus

  5. #5
    Membre à l'essai
    Femme Profil pro
    Développeur Web
    Inscrit en
    Mai 2014
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 49
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Mai 2014
    Messages : 24
    Points : 16
    Points
    16
    Par défaut

    Je suis un peu perdue du coup...

    je comprend ta démarche, mais je suis moins à l'aise avec ton code...

    alors comment mixer la première fonction avec la tienne ?
    dois-je mettre les deux fonctions les unes sous les autres ? mais quelles sont les variables que je fais passer ?

    j'ai fait un test :
    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
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    function search($wordSearch, $text, $nbWords = 10) {
     
        //On enlève la ponctuation pour la recherche
        $carToReplace = array('.', ',', '?', '!', ':', ';', '"', '...', '(', ')', "'");
     
        $textToSearch = str_replace($carToReplace, "", $text);
     
        $tabTextToSearch = explode(" ", $textToSearch);
        $tabText = explode(" ", $text);
     
        $resSearch = array_search($wordSearch, $tabTextToSearch);
        if ($resSearch === false) {
            return false;
        }
     
        $indexFirstWord = $resSearch - $nbWords;
        if ($indexFirstWord < 0) {
            $indexFirstWord = 0;
        }
     
        $before = array_slice($tabText, $indexFirstWord, $nbWords);
        $after = array_slice($tabText, $resSearch + 1, $nbWords);
     
        return array(
            implode(' ', $before),
            '<strong>'.$wordSearch.'</strong>',
            implode(' ', $after),
        );
    }
     
    $text = "Voici un texte de texte, dans lequel on va chercher un mot en particulier et qui affichera (ceci est un test) les '10 mots' qui se situe avant et après ce mot, pour voir comment c'est facile d'utiliser les tableaux en php.";
     
    $wordSearch = "après";
     
    $resSearch = search($wordSearch, $text);
     
    if ($resSearch !== false) {
        echo implode(" ",$resSearch);
    } else {
        echo "Mot non trouvé dans la chaîne";
    }
    ////////
     
     function getExcerpt($needle, $str) {
        $pattern = '~((?:\p{Xan}+\P{Xan}+){0,10}?)(' . preg_quote($needle, '~') . ')((?:\P{Xan}+\p{Xan}+){0,10})~i';    
        if (preg_match($pattern, $str, $match)) 
            return $match[1] . '<strong>' . $match[2] . '</strong>' . $match[3];
        else
            return false;
    }
    getExcerpt($texte,$wordSearch);
    et j'obtiens :
    Warning: preg_match() [function.preg-match]: Compilation failed: unknown property name after \P or \p at offset 10 in /web/.....test-chaine2.php on line 48

  6. #6
    Expert éminent Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 858
    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 858
    Points : 6 556
    Points
    6 556
    Par défaut
    En fait non, les deux approches sont différentes. Celle que je présente utilise les expressions régulières , l'autre utilise les manipulations de tableaux. Je te conseille d'utiliser l'approche avec laquelle tu te sens le plus à l'aise dans un premier temps, quitte à revenir à l'autre ensuite.

    Voici un exemple d'utilisation. J'ai modifier la fonction pour que le nombre de mots soit pris en compte:
    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
    $text = "Voici un texte de texte, dans lequel on va chercher un mot en particulier et qui affichera (ceci est un test) les '10 mots' qui se situe avant et après ce mot, pour voir comment c'est facile d'utiliser les tableaux en php.";
     
    $wordSearch = "après";
     
    function getExcerpt($needle, $str, $limit = 10) {
        $pattern = '~((?:\p{Xan}+\P{Xan}+){0,' . $limit .'}?)(' . preg_quote($needle, '~')
                 . ')((?:\P{Xan}+\p{Xan}+){0,' . $limit . '})~iu';    
        if (preg_match($pattern, $str, $match)) 
            return $match[1] . '<strong>' . $match[2] . '</strong>' . $match[3];
        else
            return false;
    }
     
    var_dump (getExcerpt($wordSearch, $text, 5));
    var_dump (getExcerpt($wordSearch, $text));
    var_dump (getExcerpt('choucroute', $text, 8));
    Il est possible si tu utilises une version de PHP pas trop récente que \p{Xan} ne soit pas encore disponible (d'où le warning). Dans ce cas tu peux modifier le pattern:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $pattern = '~((?:[\p{L}\p{N}]+[^\p{L}\p{N}]+){0,' . $limit .'}?)(' . preg_quote($needle, '~')
             . ')((?:[^\p{L}\p{N}]+[\p{L}\p{N}]+){0,' . $limit . '})~iu';
    Ce qui revient au même (\p{L} pour les lettres, \p{N} pour les chiffres, [\p{L}\p{N}] => un chiffre ou une lettre)
    Brachygobius xanthozonus
    Ctenobrycon Gymnocorymbus

  7. #7
    Membre expert
    Avatar de Spartacusply
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mai 2011
    Messages
    1 723
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mai 2011
    Messages : 1 723
    Points : 3 274
    Points
    3 274
    Par défaut
    j'ai par contre remarqué un souci qui est aussi présent dans ta version, et qui me semble un peut gênant :
    lorsqu'il y a moins de 10 mots avant le mot recherché, il affiche 10 mots (dont le mot recherché), puis il affiche la suite, dont une partie est donc en doublon.
    exemple :
    avec le mot "lequel" en recherche, j'ai ceci :
    "Voici un texte de texte, dans lequel on va chercher lequel on va chercher un mot en particulier et qui affichera"
    doublon de "lequel on va chercher"
    Ah oui en effet il y a quelque chose à changer, on ne vas plus afficher 10 mots s'il n'y a pas 10 mots avant.

    Voici la fonction modifiée (à partir la ligne 18) :

    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
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    <?php
     
    function search($wordSearch, $text, $nbWords = 10) {
     
        //On enlève la ponctuation pour la recherche
        $carToReplace = array('.', ',', '?', '!', ':', ';', '"', '...', '(', ')', "'");
     
        $textToSearch = str_replace($carToReplace, "", $text);
     
        $tabTextToSearch = explode(" ", $textToSearch);
        $tabText = explode(" ", $text);
     
        $resSearch = array_search($wordSearch, $tabTextToSearch);
        if ($resSearch === false) {
            return false;
        }
     
        $nbWordsBefore = $nbWords;
        $indexFirstWord = $resSearch - $nbWords;
        if ($indexFirstWord < 0) {
            $nbWordsBefore = $nbWords + $indexFirstWord;
            $indexFirstWord = 0;
        }
     
        $before = array_slice($tabText, $indexFirstWord, $nbWordsBefore);
        $after = array_slice($tabText, $resSearch + 1, $nbWords);
     
        return array(
            'before' => implode(' ', $before),
            'word' => $wordSearch,
            'after' => implode(' ', $after),
        );
    }
     
    $text = "Voici un texte de texte, dans lequel on va chercher un mot en particulier et qui affichera (ceci est un test) les '10 mots' qui se situe avant "
            . "et après ce mot, pour voir comment c'est facile d'utiliser les tableaux en php.";
     
    $wordSearch = "lequel";
     
    $resSearch = search($wordSearch, $text);
     
    if ($resSearch !== false) {
        print_r($resSearch);
    } else {
        echo "Mot non trouvé dans la chaîne";
    }
    Concernant les 2 méthodes proposées, personnellement je préfère privilégier la manipulation de tableau dès que je le peut car je trouve ça compréhensible et plus lisible. Après la solution des expressions régulières, proposée par CosmoKnacki, est très bien aussi mais je m'y sens personnellement beaucoup moins à l'aise. Je doit aussi avouer que sur des très longs textes (plusieurs millers de mots), cette méthode est sans doute plus performante.

    Et une dernière chose, tu peux simplifier le retour de ta fonction pour afficher une phrase directement :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    return implode(' ', $before) . '<strong>' . $wordSearch . '</strong>' . implode(' ', $after);
    Un message utile vous a aidé ? N'oubliez pas le

    www.simplifions.fr - Simplifier vos comptes entre amis !

  8. #8
    Expert éminent Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 858
    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 858
    Points : 6 556
    Points
    6 556
    Par défaut
    La méthode que j'ai proposée est en fait bien plus lente (que ce soit pour des petites ou longues chaînes avec ou sans le mot recherché) et ce, du fait qu'à chaque mot rencontré dans la chaîne, les 9 mots suivants sont testés pour voir s'il ne s'agit pas du mot recherché. Il en résulte un perte de temps énorme. Je l'ai donc réécrite dans une optique de performance en évitant ce problème:

    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
    function getExcerpt2 ($needle, $str, $limit = 10) {
        $offset = 0;
        $needleLength = strlen($needle);
        $pattern = '~(?<=\P{Xan}|\A)' . preg_quote($needle, '~') . '(?=\P{Xan}|\z)\K(?>\P{Xan}+\p{Xan}+){0,' . $limit . '}+~iu';
        // $pattern = '~(?<=[^\pL\pN]|\A)' . preg_quote($needle, '~') . '(?=[\pL\pN]|\z)\K(?>[^\pL\pN]+[\pL\pN]+){0,' . $limit . '}+~iu';
        while (false !== $offset = stripos($str, $needle, $offset)) {
            if (preg_match($pattern, $str, $match, null, $offset)) {
                $after = $match[0];
     
                preg_match('~(?>\P{Xan}+\p{Xan}+){0,' . $limit . '}~Au', strrev(substr($str, 0, $offset)), $match); // ~(?>[^\pL\pN]+[\pL\pN]+){0,' . $limit . '}+~Au
                $before = strrev($match[0]);
     
                $result = $before . $needle . $after;
                break;
            } else {
                $offset += $needleLength;
            }
        }
        return (isset($result))? $result : false;
    }
    L'idée est de parcourir la chaîne le moins possible. Tout d'abord la fonction stripos se charge de localiser un mot recherché potentiel (Je dis potentiel car stripos ne permet pas de distinguer si un mot est seul ou à l'intérieur d'un autre mot). Ensuite, avec preg_match on vérifie que le mot est bien isolé avec un test arrière (?<=\P{Xan}|\A) (précédé par un caractère qui n'est ni une lettre ni un chiffre ou le début de chaîne) et un test avant (?=\P{Xan}|\z) (suivi par un caractère qui n'est ni une lettre ni un chiffre ou la fin de la chaîne), et on en profite pour récupérer les 10 mots suivants. Le \K sert à enlever du résultat tous ce qui correspond au sous-pattern à sa gauche (il ne reste donc que les 10 mots dans $match[0]).

    Puis pour éviter le problème de tout à l'heure, on extrait la sous chaîne avant le mot et on la retourne avec strrev, ce qui permet d'extraire rapidement les 10 mots précédents avec un pattern ancré en début de chaîne (~A), vu qu'ils se retrouvent au début de la chaîne (écrits à l'envers certes, mais ils y sont).

    Les principaux atouts de cette nouvelle version sont l'utilisation des fonctions stripos, strrev et substr qui sont des opérations rapides, le fait que la chaîne ne soit parcourue qu'une seule fois, et le fait d'utiliser un motif de recherche pour les 10 mots précédents qui soit ancré.
    Brachygobius xanthozonus
    Ctenobrycon Gymnocorymbus

  9. #9
    Membre à l'essai
    Femme Profil pro
    Développeur Web
    Inscrit en
    Mai 2014
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 49
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Mai 2014
    Messages : 24
    Points : 16
    Points
    16
    Par défaut
    Bonjour CosmoKnacki et Spartacusply

    Tout d'abord merci à tous les deux de votre aide et votre implication, ça fait chaud au cœur quand on est planté pendant des heures de trouver une aide salutaire

    Spartacusply : j'ai repris la dernière version de ton code, étant donné que j'avais commencé avec celle-ci ça m'était plus simple.
    Dans le code que tu as mis j'ai eu une erreur "Warning: implode() [function.implode]: Invalid arguments passed ..."
    qui me renvoyait à cette ligne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    return implode(' ', $before) . '<strong>' . $wordSearch . '</strong>' . implode(' ', $after);
    j'ai donc repris la modification que j'avais faite précédemment, en intégrant tes corrections. Le mix des deux, qui fonctionne bien est celui-ci :
    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
    37
    38
    39
    40
    41
    42
    43
    44
    45
    function search($wordSearch, $text, $nbWords = 10) {
     
        //On enlève la ponctuation pour la recherche
        $carToReplace = array('.', ',', '?', '!', ':', ';', '"', '...', '(', ')', "'");
     
        $textToSearch = str_replace($carToReplace, "", $text);
     
        $tabTextToSearch = explode(" ", $textToSearch);
        $tabText = explode(" ", $text);
     
        $resSearch = array_search($wordSearch, $tabTextToSearch);
        if ($resSearch === false) {
            return false;
        }
     
        $nbWordsBefore = $nbWords;
        $indexFirstWord = $resSearch - $nbWords;
        if ($indexFirstWord < 0) {
            $nbWordsBefore = $nbWords + $indexFirstWord;
            $indexFirstWord = 0;
        }
     
        $before = array_slice($tabText, $indexFirstWord, $nbWordsBefore);
        $after = array_slice($tabText, $resSearch + 1, $nbWords);
     
        return array(
            implode(' ', $before),
            '<strong>'.$wordSearch.'</strong>',
            implode(' ', $after),
        );
    }
     
    $text = "Voici un texte de texte, dans lequel on va chercher un mot en particulier et qui affichera (ceci est un test) les '10 mots' qui se situe avant "
            . "et après ce mot, pour voir comment c'est facile d'utiliser les tableaux en php.";
     
    $wordSearch = "lequel";
     
    $resSearch = search($wordSearch, $text);
     
    if ($resSearch !== false) {
        //print_r($resSearch);
    	echo implode(" ",$resSearch);
    } else {
        echo "Mot non trouvé dans la chaîne";
    }
    CosmoKnacki : j'ai tout de même testé ta solution, et il semble qu'il y ait un souci dans le code par ici :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    // $pattern = '~(?<=[^\pL\pN]|\A)' . preg_quote($needle, '~') . '(?=[\pL\pN]|\z)\K( ?>[^\pL\pN]+[\pL\pN]+){0,' . $limit . '}+~i';
    et ici :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     preg_match('~(?>\P{Xan}+\p{Xan}+){0,' . $limit . '}~A', strrev(substr($str, 0, $offset)), $match); // ~(?>[^\pL\pN]+[\pL\pN]+){0,' . $limit . '}+~A
    car les ?> qui sont dans les lignes ferment l'interprétation php.
    Pour tester j'ai enlevé les lignes de commentaires en entier, vu que ça n'est pas indispensable.
    la façon de coder étant très éloignée de ma compréhension (mais c'est quoi cet alignement de petits signes ?) je suis carrément incapable de retoucher quoi que ce soit.

    En l'état rien ne s'affiche, j'ai donc ajouté l'utilisation de la fonction et la déclaration des variables :

    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
    function getExcerpt2 ($needle, $str, $limit = 10) {
        $offset = 0;
        $needleLength = strlen($needle);
        $pattern = '~(?<=\P{Xan}|\A)' . preg_quote($needle, '~') . '(?=\P{Xan}|\z)\K(?>\P{Xan}+\p{Xan}+){0,' . $limit . '}+~i';
        while (false !== $offset = stripos($str, $needle, $offset)) {
            if (preg_match($pattern, $str, $match, null, $offset)) {
                $after = $match[0];
     
                preg_match('~(?>\P{Xan}+\p{Xan}+){0,' . $limit . '}~A', strrev(substr($str, 0, $offset)), $match); 
                $before = strrev($match[0]);
     
                $result = $before . $needle . $after;
                break;
            } else {
                $offset += $needleLength;
            }
        }
        return (isset($result))? $result : false;
    }
    $text = "Voici un texte de texte, dans lequel on va chercher un mot en particulier et qui affichera (ceci est un test) les '10 mots' qui se situe avant et après ce mot, pour voir comment c'est facile d'utiliser les tableaux en php.";
    		$wordSearch = "lequel";
    		echo getExcerpt2 ($text,$wordsearch);
    je pense que je ne suis pas loin de la solution, mais je reste plantée.
    J'ai intégré la version de Spartacusply, toutefois, pour ceux qui pourraient préférer ta version, tu souhaiteras peut-être y apporter des précisions.

    je met le post en "résolu", et vous remercie encore.

    Bonne journée !

  10. #10
    Expert éminent Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 858
    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 858
    Points : 6 556
    Points
    6 556
    Par défaut
    L'utilisation de ?> dans un commentaire ou une chaîne de caractère ne doit normalement pas être vu comme un tag de fermeture pour l'interpréteur PHP. Les deux commentaires dans le code de la fonction sont là pour que tu remplaces les deux patterns qui utilise \p{Xan} qui visiblement n'est pas supporté par ta version de PHP. Pour tester la fonction tu dois donc faire le remplacement.

    Tu as inversé les arguments de la fonction, elle s'utilise comme ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    echo getExcerpt2 ($wordsearch, $text);
    Brachygobius xanthozonus
    Ctenobrycon Gymnocorymbus

  11. #11
    Membre à l'essai
    Femme Profil pro
    Développeur Web
    Inscrit en
    Mai 2014
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 49
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Mai 2014
    Messages : 24
    Points : 16
    Points
    16
    Par défaut
    Pour aller "jusqu'au bout", je viens de tester.

    j'ai maintenant ceci :
    Warning: stripos() [function.stripos]: needle is not a string or an integer in /web/...php on line 5
    qui renvoie à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    while (false !== $offset = stripos($str, $needle, $offset)) {

  12. #12
    Expert éminent Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 858
    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 858
    Points : 6 556
    Points
    6 556
    Par défaut
    Si tu obtiens ça, c'est que tu ne passes pas un chaîne de caractère en second paramètre à la fonction (il te le dis), c'est probablement une erreur de frappe.
    Brachygobius xanthozonus
    Ctenobrycon Gymnocorymbus

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Comment manipuler une chaine de caractère
    Par belmehdi17 dans le forum Débuter avec Java
    Réponses: 2
    Dernier message: 11/03/2008, 16h03
  2. Manipulation de chaine de caractères, supression d'une apostrophe
    Par pmithrandir dans le forum Scripts/Batch
    Réponses: 6
    Dernier message: 28/11/2007, 07h55
  3. Manipulation des chaines de caractères en c
    Par developppez dans le forum C
    Réponses: 8
    Dernier message: 29/04/2007, 13h04
  4. Réponses: 4
    Dernier message: 14/10/2006, 23h38
  5. Réponses: 4
    Dernier message: 20/08/2004, 10h59

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