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 :

regex avec les caractères accentués (en russe) [RegEx]


Sujet :

Langage PHP

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 5
    Par défaut regex avec les caractères accentués (en russe)
    Bonjour,
    J'apprends actuellement le russe.
    Je chercher à créer une expression régulière pour repérer les mots dans un texte qu'ils soient accentués ou non. Je cherche uniquement les mots entiers (en utf8).
    Le russe ne possède pas de lettres accentuées, mais lorsqu'on apprend le russe, les textes peuvent posséder des accents aigus sur les voyelles pour aider à prononcer les mots correctement.

    Voici les fonctions que j'ai écrites:

    function regExpWordWithOrWithoutStress($word){
    $without_accent = array("а","э","ы","у","о","я","е","ю","и");
    $with_accent = array(
    "(а|а\p{M})",
    "(э|э\p{M})",
    "(ы|ы\p{M})",
    "(у|у\p{M})",
    "(о|о\p{M})",
    "(я|я\p{M})",
    "(е|ё|е\p{M})",
    "(ю|ю\p{M})",
    "(и|и\p{M})");
    $word_ready = str_replace($without_accent, $with_accent, $word);
    return $word_ready;
    }
    function regExpFindWord($word){

    $search = regExpWordWithOrWithoutStress($word);
    $regExp = "/(?<!\pL)".$search."(?!\pL)/ui";

    return $regExp;

    }

    Note: Je n'utilise pas les balises de code pour que les caractères russes puissent s'afficher correctement dans le code.

    Mon problème est le suivant:
    Lorsque je cherche le mot и un petit mot russe qui signifie "et" dans le texte

    И вот прихожу́ я в э́тот моме́нт в министе́рство, а за столо́м сиди́т не бу́дем говори́ть кто, и вычёркивает из уче́бника и́мя Алекса́ндра Меня́.

    avec l'expression régulière

    (?<!\pL)(и|и\p{M})(?!\pL)

    les deux premiers и sont bien reconnus, mais le и de и́мя est aussi sélectionné alors que je ne cherche que les mots entiers...

    Comment modifier l'expression régulière pour que seuls les deux premiers и soient bien pris en compte?

  2. #2
    Membre expérimenté Avatar de daniel61
    Inscrit en
    Décembre 2006
    Messages
    139
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 139
    Par défaut
    Bonjour,
    Je ne connais rien au russe mais selon tes explications je ne vois pas mieux que de bloquer la possibilité de backtracking sur и car \pM matchera (?!\pL)

    peut-être trop restrictif ?
    /(?<!\pL)(и|и\pM)(?!\pL|\pM)/ui

    ou bien moins restrictif ?
    /(?<!\pL)(и(?!\pM)|и\pM)(?!\pL)/ui

    ou encore avec (*SKIP) en inversant l'alternative ?
    /(?<!\pL)(и\pM(*SKIP)|и)(?!\pL)/ui

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 5
    Par défaut
    Fantastique!

    J'ai opté pour ajouter également |\pM au début pour éviter le cas suivant:
    En russe, "с" est également un petit mot qui signifie avec.
    Dans la phrase : "вы ви́дите Украи́ну с Аме́рикой", "с Евро́пой", и́ли "с Росси́ей" […]
    Хотя́ э́то был станда́ртный опро́с.
    Le c de опро́с était pris en compte par l'expression régulière (probablement parce qu'il y avait un accent juste avant).

    Ce qui donne
    $regExp = "/(?<!\pL|\pM)".$search."(?!\pL|\pM)/ui";

    Par exemple:
    /(?<!\pL|\pM)(и|и\pM)(?!\pL|\pM)/ui

    Merci énormément!

  4. #4
    Expert confirmé Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 986
    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 986
    Par défaut
    Il est plus simple de changer l'ordre de tes alternatives en commençant par la plus longue car lorsque plusieurs alternatives sont testées c'est la première qui réussit qui gagne (et pas la plus longue), mais dans ce cas précis, il suffit de rendre optionnel le caractère combinant, donc:
    $with_accent = array(
    "(а\pM?+)",
    "(э\pM?+)",
    "(ы\pM?+)",
    "(у\pM?+)",
    "(о\pM?+)",
    "(я\pM?+)",
    "(е\pM?+|ё)",
    "(ю\pM?+)",
    "(и\p{M}?+)");

    (En passant, les groupes de captures sont-ils vraiment nécessaires? Si ce n'est pas le cas tu peux tous les enlever sauf dans le cas de "(е\pM?+|ё)" où un groupe non capturant sera plus approprié: "(?:е\pM?+|ё)" ou mieux encore un groupe atomic "(?>е\pM?|ё)" ce qui permet d'enlever le quantificateur possessif.)

    Puis pour la pattern:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $pattern = '~(?<![\pL\pM])' . $search . '(?!\pL)~ui';

    Les quantificateurs possessifs ?+ sont importants car si (?!\pL) échoue après un caractère combinant, le quantificateur ? devra rendre le caractère pour que (?!\pL) puisse réussir dessus. En rendant un quantificateur possessif on empêche ce mécanisme de backtracking. (voir le test)

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 5
    Par défaut
    Merci!
    effectivement les groupes de captures ne sont pas nécessaires vu qu'il s'agit de capturer uniquement les mots entiers

    dans mon mini-projet: les mots connus sont rentrés sans accent dans la base de données, puis, lorsque je lis un texte russe,
    les mots apparaissent en noir s'ils sont dans la bdd, en bleu s'ils n'y sont pas.
    la mise à jour de la bdd se fait "en direct", en cliquant sur un mot (le mot inconnu --> connu, le mot connu --> inconnu [si j'ai oublié le sens du mot]) [en utilisant jquery + ajax]

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

Discussions similaires

  1. Problème avec les caractères accentués
    Par abbd dans le forum Windows Forms
    Réponses: 6
    Dernier message: 13/02/2009, 17h40
  2. [MySQL] Probléme avec les caractéres accentués suite à un export
    Par UNi[FR] dans le forum PHP & Base de données
    Réponses: 1
    Dernier message: 17/05/2006, 09h10
  3. [SQL-Server] ms sql server et php : problème avec les caractères accentués
    Par stephane9422 dans le forum PHP & Base de données
    Réponses: 6
    Dernier message: 05/12/2005, 17h45
  4. [AJAX] Problèmes avec les caractères accentués
    Par marti dans le forum Servlets/JSP
    Réponses: 10
    Dernier message: 26/10/2005, 14h10
  5. Réponses: 5
    Dernier message: 04/09/2005, 12h34

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