Joseph Tux
Un aide-mémoire plus bref que {perlretut},

Parenthèses non capturantes dans les expressions rationnelles de Perl

mardi 11 janvier 2011

Les parenthèses simples sont utiles pour capturer une ou plusieurs séquences dans une chaine reconnue par l’ expression rationnelle. Mais elle sont couteuses en mémoire et autres ressources.

Pour regrouper des éléments, il existent donc les parenthèses non-capturantes.

Des conditions de reconnaissance d’une partie de chaine en fonction de critères peuvent aussi être indiquées avec des notations parenthèsées.

  • Ces parenthèses ne comptent pas dans la numérotation des captures
  • La notation spéciale ne concerne pas la parenthese fermante, notée simplement « ) »
     [1]

$x = « a » ; # se lit $x vaut « a », ou $x contient « a »
$x = /regex/ ; # se lit $x est reconnu par la regex

 GROUPEMENT

  1. (?:
    1. Avantage : économie de mémoire et de travail

 TEST AVANT<span class= [2] ' />

  1. (?= Condition positive
  2. (?! Condition négative
    1. La recherche peut continuer seulement s la condition est remplie
    2. Exemples
      1. Bill(?= The Cat | Clinton ) ne reconnaît Bill que s’il est suivi de « The Cat » ou de « Clinton »
      2. (?=(.*)) simuler $’ (économie d’énergie ++ )
      3. (?!000)\d\d\d ne reconnaître 3 chiffres que s’il ne sont pas « 000 »
        (et non pas « s’ils ne sont pas précédés de »000")
      4. piège subtile
        _ \d+(?!\.) reconnaît 56789 dans ’F 56789’
        \d+(?=[^.] reconnaît 5678 dans ’F 56789’
        Pour reconnaître à coup sur un nombre sauf s’il est suivi d’un point , il faut écrire :
        \d+(?=[^.\d])

 TEST ARRIERE<span class= [3] ' />

  • Ne fontionne qu’avec des regex de longueur fixe
  • Utile en cas d’alternative ou de quantificateur
  1. (?<= = ne pas revenir sur « une reconnaissance réussie »
  2. (?<! = ne pas revenir sur « aucune reconnaissance réussie »

 COMMENTAIRES

  • Le modificateur /x permet d’ignorer les commentaires (et aussi les espaces) [4] dans toute la regex.
  1. (?# est traité comme un commentaire jusqu’à la parenthèse fermante, c’est à dire ignoré, à condition d’échapper les copies du délimiteur d’opérante [5]

 SOUS-EXPRESSIONS INDÉPENDANTES

_* (?>regexp)

exemple [6] :

ANALOGIE AVEC /g et \G :

$x = "ab";
$x =~ /a*/g ;     # reconnu, consomme le 'a', g marque l'offset
$x =~ /\Gab/g ; # pas reconnu, car 'a' n'est plus disponible

REGEX plus compliquée et pathologiquement lente [7] durée croissant de façon exponentielle en cas de non reconnaissance :

$x = "abc(de/fg)h" ;   # une parenthèse non refermée
$x =~ / \( ( [^()]+  |  \([^()]* \) )+ \)/x ;

AVEC (?> :
$x = / \( ( (?>[^()]+) | \([^()]*\) )+ \) /x ;


 MODIFICATEURS LOCAUX<span class= [8] ' />

  • les modificateurs comme /x /m /s /i ( /xmsi par exempel ! ), sont utilisables avec
  1. (?i) insensible à la casse
  2. (?x) commentaires et blancs ignorés
  3. (?m) multiligne (^ et $) Caractère nouvelle ligne reconnue au milieu d’une chaine
  4. (?s) simple ligne ( . ) Caractère nouvelle ligne = caractère ordinaire, et le point aussi
  5. et leurs combinaisons : (?xms)
    /ms = reconnaît tout avec le point (« multiligne propre » selon Chouette [9], p237 sqq)

 RÉFÉRENCES ARRIÈRES NOMMÉES

un groupe [10] peut s’écrire :

(?<nom>groupe_regex) ou (?'nom' groupe_regex)

et plus loin dans la regex, la référence s’écrit : \g{nom}

Dans le code Perl, les captures sont accessibles dans {{%+}} [11]

 NUMÉROTATION DES GROUPES DANS UNE ALTERNATIVE<span class= [12] ' />

 [13]

(?|

(?| (\d\d|\d):(\d\d)|(\d\d) ....... [14]

Voir aussi la documentation en Français

[1Pour une lecture plus simple, je n’expose ni la partie regex, ni la parenthèse fermante

[2Généralisation du concept d'ancre (comme ^,$,\A,\z,\b etc..), ne consomme pas de carcatère

[3cf Damian Conway De l'art de programmer en Perl, O'Reilly, ed. française, p275-277
et perlretut

[4Sauf les délimiteurs ( "/" ou "{" et "}" ) qui doivent être échappés

[5comme « / » ou «  » et «  » , qui sont les seuls habituellement recommandés, par Damian (sauf s’ils occupent aussi la regex)

[6de perlretut

[7à cause des quantificateurs imbriqués, comme (a+|b)+

[8seule la partie de la regex entre ces parenthèses est affectée

[9« Maîtrise des expressions régulières » Traduction Française, O’Reilly Jeffrey E.F.Friedl traduction : L.Dami

[10une partie de la regex

[11soit $+0 à $+$#

[12depuis Perl 5.10

[13TODO

[14-* à l’intérieur de l’alternative, pour chaque branche, la numérotation des groupes commencent à la même position

  • après l’alternative, la numérotation continue à partir du numéro le plus élevé qu’une branche de l’alternative ait atteint
Voir en ligne : perlretut (en Français)

Accueil | Contact | Plan du site | | Statistiques du site | Visiteurs : 105 / 57757

Suivre la vie du site fr  Suivre la vie du site GNU, LINUX, BSD, LL  Suivre la vie du site AIDES GNU/LINUX  Suivre la vie du site PERL   ?

Site réalisé avec SPIP 3.1.6 + AHUNTSIC

Creative Commons License