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 :

Clarification sur "positive look ahead" [RegEx]


Sujet :

Langage PHP

  1. #1
    Membre régulier
    Profil pro
    Développeur informatique
    Inscrit en
    Mars 2008
    Messages
    80
    Détails du profil
    Informations personnelles :
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2008
    Messages : 80
    Points : 114
    Points
    114
    Par défaut Clarification sur "positive look ahead"
    Bonjour,

    J'ai étudié les constructions suivantes :

    • positive look behind
    • positive look ahead
    • negative look behind
    • negative look ahead


    D'après ce que j'ai compris, ces constructions désignent un caractère en fonction d'une condition :

    • positive look behind: désigne un caractère à condition que ce dernier soit précédé par un caractère donné.
    • positive look ahead: désigne un caractère à condition que ce dernier soit suivi par un caractère donné.
    • negative look behind: désigne un caractère à condition que ce dernier ne soit pas précédé par un caractère donné.
    • negative look ahead: désigne un caractère à condition que ce dernier ne soit pas suivi par un caractère donné.


    Sauf que la construction "positive look ahead" ne désigne pas un caractère, mais deux.

    Illustration en Python :

    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
    from typing import Optional, Pattern, Match
    import re
     
    print("Positive look-ahead: a(?:b) ('a' followed by 'b')")
    p: Pattern = re.compile('a(?:b)')
    text: str = 'abc'
    m: Optional[Match] = p.search(text)
    print(f'{text} => {m.group(0)}')  # => ab
    print('')
     
    # Negative look-ahead: "a" is not followed by "b".
     
    print("Negative look-ahead: a(?!b) ('a' not followed by 'b')")
    p: Pattern = re.compile('a(?!b)')
    text: str = 'ax'
    m: Optional[Match] = p.match(text)
    print(f'{text} => {m.group(0)}')  # => a
    print('')
     
    # Negative look-behind: "b" is not preceded by "a".
     
    print("Negative look-behind: (?<!a)b ('b' not preceded by 'a')")
    p: Pattern = re.compile('(?<!a)b')
    text: str = 'xb'
    m: Optional[Match] = p.search(text)
    print(f'{text} => {m.group(0)}')  # => b
    print('')
     
    # Positive look-behind: "b" is preceded by "a".
     
    print("Positive look-behind: (?<=a)b ('b' preceded by 'a')")
    p: Pattern = re.compile('(?<=a)b')
    text: str = 'ab'
    m: Optional[Match] = p.search(text)
    print(f'{text} => {m.group(0)}')  # => b
    print('')
    Le résultat :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Positive look-ahead: a(?:b) ('a' followed by 'b')
    abc => ab
     
    Negative look-ahead: a(?!b) ('a' not followed by 'b')
    ax => a
     
    Negative look-behind: (?<!a)b ('b' not preceded by 'a')
    xb => b
     
    Positive look-behind: (?<=a)b ('b' preceded by 'a')
    ab => b
    Le m'attendais à ce que "a(?:b)" retourne "a" et non "ab".

    Quelqu'un pourrait-il m'expliquer la logique derrière ce résultat ?

    Merci.



    Ajout

    L'utilisation de Perl retourne les mêmes résultats :

    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
    use strict;
     
    if ('ab' =~ m/a(?:b)/) {
    	print("${&}\n")  # => ab
    }
     
    if ('ax' =~ m/a(?!b)/) {
    	print("${&}\n")  # => a
    }
     
    if ('xb' =~ m/(?<!a)b/) {
    	print("${&}\n")  # => b
    }
     
    if ('ab' =~ m/(?<=a)b/) {
    	print("${&}\n")  # => b
    }

  2. #2
    Expert éminent Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 888
    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 888
    Points : 6 632
    Points
    6 632
    Par défaut
    D'après ce que j'ai compris, ces constructions désignent un caractère en fonction d'une condition
    Tu as mal compris ou on t'a mal expliqué. Ces constructions vérifient une condition à la position courante dans la chaîne sujet (position à laquelle se trouve le moteur de regex au moment où il la rencontre). Cette condition est une sous-pattern qui, si elle est trouvée ou pas, va faire réussir ou échouer le moteur de regex à la position courante. La sous-pattern peut être n'importe quoi (et pas seulement un caractère unique).

    Ces constructions sont des assertions au même titre que par exemple une ancre de début ou de fin de chaîne. Comme toutes les assertions, celles-ci ne consomment pas les caractères de la chaîne, elles se contentent de faire des vérifications en cours de route.

    Dans ton programme, tu t'es trompé sur la syntaxe du lookahead: (?:...) est un groupe non-capturant, ce n'est pas un lookahead. Le positive lookahead (test avant positif) s'écrit: (?=...). D'où ton erreur.

  3. #3
    Membre régulier
    Profil pro
    Développeur informatique
    Inscrit en
    Mars 2008
    Messages
    80
    Détails du profil
    Informations personnelles :
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2008
    Messages : 80
    Points : 114
    Points
    114
    Par défaut Merci beaucoup pour cette explication claire.
    @CosmoKnacki

    Bonjour CosmoKnacki,

    Je reviens sur le sujet tardivement, mais je ne suis pas déçu par ce que je trouve !

    Merci beaucoup pour cette explication claire. Effectivement, je n'avais pas compris la nature de cette construction.

    C'est beaucoup plus claire.

    Cordialement,

    Denis

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

Discussions similaires

  1. forcer l'écriture sur 4 positions
    Par dassise dans le forum SQL Procédural
    Réponses: 1
    Dernier message: 26/10/2006, 22h28
  2. [C#] Focus sur une position
    Par annalady dans le forum Windows Forms
    Réponses: 4
    Dernier message: 03/04/2006, 23h05

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