9.7. Correspondance de motif

PostgreSQL™ fournit trois approches différentes à la correspondance de motif : l'opérateur SQL traditionnel LIKE, le plus récent SIMILAR TO (ajouté dans SQL:1999) et les expressions rationnelles de type POSIX. De plus, une fonction de correspondance de motif, substring, est disponible, qui utilise le style SIMILAR TO ou le style POSIX des expressions rationnelles.

[Astuce]

Astuce

Si des correspondances de motif qui vont au delà sont nécessaires, il faudra considérer l'écriture d'une fonction en Perl ou Tcl.

9.7.1. LIKE

chaîne LIKE motif [ESCAPE caractère d'échappement]
chaîne NOT LIKE motif [ESCAPE caractère d'échappement]

Chaque motif définit un ensemble de chaînes. L'expression LIKE renvoie true si la chaîne est contenue dans l'ensemble de chaînes représenté par le motif. (L'expression NOT LIKE renvoie false si LIKE renvoie true et vice versa. Une expression équivalente est NOT (chaîne LIKE motif)).

Si le motif ne contient ni signe pourcent ni tiret bas, alors il ne représente que la chaîne elle-même ; dans ce cas, LIKE agit exactement comme l'opérateur d'égalité. Un tiret bas (_) dans motif correspond à un seul caractère, un signe pourcent (%) à toutes les chaînes de zéro ou plusieurs caractères.

Quelques exemples :

'abc' LIKE 'abc'    true
'abc' LIKE 'a%'     true
'abc' LIKE '_b_'    true
'abc' LIKE 'c'      false

Le modèle LIKE correspond toujours à la chaîne entière. Pour faire correspondre une séquence à l'intérieur d'une chaîne, le motif doit donc commencer et finir avec un signe pourcent.

Pour faire correspondre un vrai tiret bas ou un vrai signe de pourcentage sans qu'ils remplacent d'autres caractères, le caractère correspondant dans motif doit être précédé du caractère d'échappement. Par défaut, il s'agit de l'antislash, mais un autre caractère peut être sélectionné en utilisant la clause ESCAPE. Pour un correspondance avec le caractère d'échappement lui-même, on écrit deux fois ce caractère.

L'antislash a déjà une signification particulière dans les chaînes littérales. De ce fait, pour écrire un motif qui contient un antislash il faut écrire deux antislashs dans l'instruction SQL (en supposant que la syntaxe d'échappement de chaînes soit utilisée). Donc, pour écrire un motif qui corresponde effectivement à un antislash littéral nécessite l'écriture de quatre antislash dans l'instruction. Tout cela peut être évité en sélectionnant un autre caractère d'échappement avec ESCAPE ; un antislash n'est alors plus spécial au regard de LIKE (mais il est toujours spécial pour l'analyseur de chaînes littérales, et nécessite toujours d'être doublé).

Il est aussi possible de ne sélectionner aucun caractère d'échappement en écrivant ESCAPE ''. Ceci désactive complètement le mécanisme d'échappement, ce qui rend impossible la désactivation de la signification particulière du tiret bas et du signe de pourcentage dans le motif.

Le mot clé ILIKE est utilisé à la place de LIKE pour faire des correspondances sans tenir compte de la casse mais en tenant compte de la locale active. Ceci ne fait pas partie du standard SQL mais est une extension PostgreSQL™.

L'opérateur ~~ est équivalent à LIKE alors que ~~* correspond à ILIKE. Il existe aussi les opérateurs !~~ et !~~* représentant respectivement NOT LIKE et NOT ILIKE. Tous ces opérateurs sont spécifiques à PostgreSQL™.

9.7.2. Expressions rationnelles SIMILAR TO

chaîne SIMILAR TO motif [ESCAPE caractère d'échappement]
chaîne NOT SIMILAR TO motif [ESCAPE caractère d'échappement]

L'opérateur SIMILAR TO renvoie true ou false selon que le motif correspond ou non à la chaîne donnée. Il est assez similaire à LIKE à la différence qu'il interprète le motif en utilisant la définition SQL d'une expression rationnelle. Les expressions rationnelles SQL sont un curieux mélange de la notation LIKE et de la notation habituelle des expressions rationnelles.

À l'instar de LIKE, l'opérateur SIMILAR TO ne réussit que si son motif correspond à la chaîne entière ; ceci ne ressemble pas aux pratiques habituelles des expressions rationnelles où le modèle peut se situer n'importe où dans la chaîne. Ainsi comme LIKE, SIMILAR TO utilise _ et % comme caractères joker dénotant respectivement tout caractère unique et toute chaîne (ils sont comparables à . et .* des expressions rationnelles compatibles POSIX).

En plus de ces fonctionnalités empruntées à LIKE, SIMILAR TO supporte trois méta-caractères de correspondance de motif empruntés aux expressions rationnelles de POSIX :

  • | dénote une alternative (une des deux alternatives) ;

  • * dénote la répétition des éléments précédents, 0 ou plusieurs fois ;

  • + dénote la répétition des éléments précédents, une ou plusieurs fois ;

  • les parenthèses () peuvent être utilisées pour grouper des éléments en un seul élément logique ;

  • une expression entre crochets [...] spécifie une classe de caractères, comme dans les expressions rationnelles POSIX.

Les répétitions encadrées (? et {...}) ne sont pas permises bien qu'elles existent en POSIX. De même, le point (.) n'est pas un méta-caractère.

Comme avec LIKE, un antislash désactive la signification spéciale de tous les méta-caractères ; un autre caractère d'échappement peut être spécifié avec ESCAPE.

Quelques exemples :

'abc' SIMILAR TO 'abc'      true
'abc' SIMILAR TO 'a'        false
'abc' SIMILAR TO '%(b|d)%'  true
'abc' SIMILAR TO '(b|c)%'   false

La fonction substring avec trois paramètres, substring(chaîne, from motif, for caractère d'échappement), fournit l'extraction d'une sous-chaîne correspondant à un motif d'expression rationnelle SQL. Comme avec SIMILAR TO, le motif fourni doit correspondre à la chaîne de données entière, sinon la fonction échoue et renvoie NULL. Pour indiquer la partie du motif à retourner en cas de succès, le motif doit contenir deux occurrences du caractère d'échappement suivi d'un guillemet double ("). Le texte correspondant à la portion du motif entre ces deux marqueurs est renvoyé.

Quelques exemples :

substring('foobar' from '%#"o_b#"%' for '#')  
oob
substring('foobar' from '#"o_b#"%' for '#')   
NULL

9.7.3. Expressions rationnelles POSIX

Le Tableau 9.11, « Opérateurs de correspondance des expressions rationnelles » liste les opérateurs disponibles pour la correspondance de motifs à partir d'expressions rationnelles POSIX.

Tableau 9.11. Opérateurs de correspondance des expressions rationnelles

Opérateur Description Exemple
~ Correspondance d'expression rationnelle, en tenant compte de la casse 'thomas' ~ '.*thomas.*'
~* Correspondance d'expression rationnelle, sans tenir compte de la casse 'thomas' ~* '.*Thomas.*'
!~ Non-correspondance d'expression rationnelle, en tenant compte de la casse 'thomas' !~ '.*Thomas.*'
!~* Non-correspondance d'expression rationnelle, sans tenir compte de la casse 'thomas' !~* '.*vadim.*'

Les expressions rationnelles POSIX sont un outil de correspondance de motifs plus puissant que les opérateurs LIKE et SIMILAR TO. Beaucoup d'outils Unix comme egrep, sed ou awk utilisent un langage de correspondance de modèles similaire à celui décrit ici.

Une expression rationnelle est une séquence de caractères représentant une définition abrégée d'un ensemble de chaînes (un ensemble rationnel). Une chaîne est déclarée correspondre à une expression rationnelle si elle est membre de l'ensemble rationnel décrit par l'expression rationnelle. Comme avec LIKE, les caractères du motif correspondent exactement aux caractères de le chaîne sauf s'ils représentent des caractères spéciaux dans le langage des expressions rationnelles -- mais les expressions rationnelles utilisent des caractères spéciaux différents de ceux utilisés par LIKE. Contrairement aux motifs de LIKE, une expression rationnelle peut avoir une correspondance en toute place de la chaîne, sauf si l'expression rationnelle est explicitement ancrée au début ou à la fin de la chaîne.

Quelques exemples :

'abc' ~ 'abc'    true
'abc' ~ '^a'     true
'abc' ~ '(b|d)'  true
'abc' ~ '^(b|c)' false

La fonction substring avec deux paramètres, substring(chaîne, from motif), extrait une sous-chaîne qui correspond à un motif d'expression rationnelle POSIX. Elle renvoie NULL s'il n'y a pas de correspondance, la portion de texte correspondant au modèle dans le cas contraire. Mais si le motif contient des parenthèses, c'est la portion de texte qui correspond à la première sous-expression entre parenthèses (la première dont la parenthèse gauche apparaît) qui est renvoyée. Il est possible de placer toute l'expression entre parenthèses pour pouvoir utiliser des parenthèses à l'intérieur sans déclencher cette exception. Si des parenthèses sont nécessaires dans le motif avant la sous-expression à extraire, il faut utiliser les propriétés des parenthèses non-capturantes décrites plus bas.

Quelques exemples :

substring('foubar' from 'o.b')     oub
substring('foubar' from 'o(.)b')   u

La fonction regexp_replace substitue un nouveau texte aux sous-chaînes correspondantes des motifs d'expressions rationnelles. Elle a la syntaxe regexp_replace(source, motif, remplacement [, options ]). La chaîne source est renvoyée non modifiée s'il n'existe pas de correspondance avec motif. S'il existe une correspondance, la chaîne source est renvoyée avec la chaîne remplacement substituée à la sous-chaîne correspondante. La chaîne remplacement peut contenir \n, avec n de 1 à 9, pour indiquer que la n-ième sous-chaîne source correspondante doit être insérée. Elle peut aussi contenir \& pour indiquer que la sous-chaîne correspondant au motif entier doit être insérée. On écrit \\ pou placer un antislash littéral dans le texte de remplacement (comme toujours, les antislashs doivent être doublés dans les libellés, si la syntaxe d'échappement de chaînes est utilisée). Le paramètre options est une chaîne optionnelle de drapeaux (0 ou plus) d'une lettre qui modifie le comportement de la fonction. Le drapeau i indique une recherche insensible à la casse, le drapeau g un remplacement de chaque sous-chaîne correspondante (pas uniquement la première).

Quelques exemples :

regexp_replace('foobarbaz', 'b..', 'X')
                                   fooXbaz
regexp_replace('foobarbaz', 'b..', 'X', 'g')
                                   fooXX
regexp_replace('foobarbaz', 'b(..)', E'X\\1Y', 'g')
                                   fooXarYXazY

Les expressions rationnelles de PostgreSQL™ sont développées à partir d'un paquetage écrit par Henry Spencer. La plupart des descriptions d'expressions rationnelles ci-dessous sont copiées directement de son manuel.

9.7.3.1. Détails des expressions rationnelles

Les expressions rationnelles (ERs), telles que définies dans POSIX 1003.2, existent sous deux formes : les ER étendues ou ERE (en gros celles de egrep) et les ER basiques ou ERB (BRE en anglais) (en gros celles d'ed). PostgreSQL™ supporte les deux formes et y ajoute quelques extensions ne faisant pas partie du standard POSIX mais largement utilisées grâce à leur disponibilité dans les langages de programmation tels que Perl et Tcl. Les ER qui utilisent ces extensions non POSIX sont appelées des ER avancées ou ERA (ARE en anglais) dans cette documentation. Les ERA sont un surensemble exact des ERE alors que les ERB ont des incompatibilités de notation (sans parler du fait qu'elles sont bien plus limitées). En premier lieu sont décrits les formats ERA et ERE, en précisant les fonctionnalités qui ne s'appliquent qu'aux ERA. L'explication des différences des ERB vient ensuite.

[Note]

Note

La forme des expressions rationnelles acceptées par PostgreSQL™ peut être choisie à l'aide du paramètre d'exécution regex_flavor (décrit dans le Chapitre 17, Configuration du serveur). La configuration habituelle est advanced (NdT : pour avancées) mais il est possible de sélectionner extended (pour étendues) pour obtenir un maximum de compatibilité avec les versions antérieures à la version 7.4 de PostgreSQL™.

Une expression rationnelle est définie par une ou plusieurs branches séparées par des caractères |. Elle établit une correspondance avec tout ce qui correspond à une des branches.

Une branche contient des atomes quantifiés ou contraintes, concaténés. Elle établit une correspondance pour le premier suivi d'une correspondance pour le second, etc ; une branche vide établit une correspondance avec une chaîne vide.

Un atome quantifié est un atome éventuellement suivi d'un quantifieur unique. Sans quantifieur, il établit une correspondance avec l'atome. Avec un quantifieur, il peut établir un certain nombre de correspondances avec l'atome. Un atome est une des possibilités du Tableau 9.12, « Atomes d'expressions rationnelles ». Les quantifieurs possibles et leurs significations sont disponibles dans le Tableau 9.13, « quantificateur d'expressions rationnelles ».

Une contrainte établit une correspondance avec une chaîne vide, mais cette correspondance n'est établie que lorsque des conditions spécifiques sont remplies. Une contrainte peut être utilisée là où un atome peut l'être, sauf qu'elle ne peut pas être suivie d'un quantificateur. Les contraintes simples sont affichées dans le Tableau 9.14, « Contraintes des expressions rationnelles » ; quelques contraintes supplémentaires sont décrites plus loin.

Tableau 9.12. Atomes d'expressions rationnelles

Atome Description
(re) (où re est toute expression rationnelle) établit une correspondance avec re, la correspondance étant conservée en vue d'un éventuel report
(?:re) comme ci-dessus mais la correspondance n'est pas conservée pour report (un ensemble de parenthèses « sans capture ») (seulement pour les ERA)
. correpondance avec tout caractère unique
[caractères] une expression entre crochets, qui établit une correspondance avec tout caractères (voir la Section 9.7.3.2, « Expressions avec crochets » pour plus de détails)
\k (où k n'est pas un caractère alpha-numérique) établit une correspondance avec ce caractère, considéré comme caractère ordinaire. Par exemple, \\ établit une correspondance avec un caractère antislash
\c avec c un caractère alphanumérique (éventuellement suivi d'autres caractères) est un échappement, voir la Section 9.7.3.3, « Échappement d'expressions rationnelles » (ERA seulement ; pour les ERE et ERB, établit une correspondance avec c)
{ lorsqu'il est suivi d'un caractère autre qu'un chiffre, établit une correspondance avec l'accolade ouvrante { ; suivi d'un chiffre, c'est le début d'une limite (voir ci-dessous)
x x est un caractère unique sans signification, établit une correspondance avec ce caractère

Une ER ne peut pas se terminer par \.

[Note]

Note

L'antislash (\) a déjà une signification particulière dans les chaînes littérales PostgreSQL™. Pour écrire un motif contenant un antislash, il faut écrire deux antislashs dans l'instruction, en supposant que la syntaxe de chaîne d'échappement est utilisée.

Tableau 9.13. quantificateur d'expressions rationnelles

quantificateur Correspondance
* une séquence de 0 ou plus correspondance(s) de l'atome
+ une séquence de 1 ou plus correspondance(s) de l'atome
? une séquence de 0 ou 1 correspondance de l'atome
{m} une séquence d'exactement m correspondances de l'atome
{m,} une séquence de m ou plus correspondances de l'atome
{m,n} une séquence de m à n (inclus) correspondances de l'atome ; m ne doit pas être supérieur à n
*? version non gourmande de *
+? version non gourmande de +
?? version non gourmande de ?
{m}? version non gourmande de {m}
{m,}? version non gourmande de {m,}
{m,n}? version non gourmande de {m,n}

Les formes qui utilisent {...} sont appelées limites. Les nombres m et n à l'intérieur d'une limite sont des entiers non signés dont les valeurs vont de 0 à 255 inclus.

Les quantificateurs non gourmands (disponibles uniquement avec les ERA) correspondent aux même possibilités que leurs équivalents normaux (gourmand), mais préfèrent le plus petit nombre de correspondances au plus grand nombre. Voir la Section 9.7.3.5, « Règles de correspondance des expressions rationnelles » pour plus de détails.

[Note]

Note

Un quantificateur ne peut pas immédiatement suivre un autre quantificateur. Il ne peut pas non plus débuter une expression ou sous-expression ni suivre ^ ou |.

Tableau 9.14. Contraintes des expressions rationnelles

Contrainte Description
^ correspondance de début de chaîne
$ correspondance de fin de chaîne
(?=er) positive lookahead (recherche positive) établit une correspondance avec tout point où une sous-chaîne qui correspond à er débute (uniquement pour les ERA)
(?!er) negative lookahead (recherche négative) établit une correspondance avec tout point où aucune sous-chaîne qui correspond à re ne débute (uniquement pour les ERA)

Les contraintes « lookahead » ne doivent pas contenir de références arrières (voir la Section 9.7.3.3, « Échappement d'expressions rationnelles »), et toutes les parenthèses contenues sont considérées comme non capturantes.

9.7.3.2. Expressions avec crochets

Une expression entre crochets est une liste de caractères contenue dans []. Une correspondance est habituellement établie avec tout caractère de la liste (voir cependant plus bas). Si la liste débute par ^, la correspondance est établie avec tout caractère non compris dans la liste. Si deux caractères de la liste sont séparés par un tiret (-), il s'agit d'un raccourci pour représenter tous les caractères compris entre ces deux-là, c'est-à-dire qu'en ASCII, [0-9] correspond à tout chiffre. Deux séquences ne peuvent pas partager une limite, par exemple a-c-e. Les plages étant fortement liées à la séquence de tri (collate), il est recommandé de ne pas les utiliser dans les programmes portables.

Un ] peut être inclus dans la liste s'il en est le premier caractère (éventuellement précédé de ^). Un - peut être inclus dans la liste s'il en est le premiser ou le dernier caractère ou s'il est la deuxième borne d'une plage. Un - peut être utilisé comme première borne d'une plage s'il est entouré par [. et .] et devient de ce fait un élément d'interclassement (collating element). À l'exception de ces caractères, des combinaisons utilisant [ (voir les paragraphes suivants) et des échappements (uniquement pour les ERA), tous les autres caractères spéciaux perdent leur signification spéciale à l'intérieur d'une expression entre crochets. En particulier, \ n'est pas spécial lorsqu'il suit les règles des ERE ou des ERB bien qu'il soit spécial (en tant qu'introduction d'un échappement) dans les ERA.

Dans une expression entre crochets, un élément d'interclassement (un caractère, une séquence de caractères multiples qui s'interclasse comme un élément unique, ou le nom d'une séquence d'interclassement) entouré de [. et .] représente la séquence de caractères de cet élément d'interclassemernt. La séquence est un élément unique de la liste dans l'expression entre crochets. Une expression entre crochets contenant un élément d'interclassement multi-caractères peut donc correspondre à plusieurs caractères (par exemple, si la séquence d'interclassement inclut un élément d'interclassement ch, alors l'ER [[.ch.]]*c établit une correspondance avec les cinq premiers caractères de chchcc.

[Note]

Note

PostgreSQL™ n'a pas, à ce jour, d'éléments d'interclassement multi-caractères. L'information porté ici décrit un éventuel comportement futur.

Dans une expression entre crochets, un élément d'interclassement écrit entre [= et =] est une classe d'équivalence qui représente les séquences de caractères de tous les éléments d'interclassement équivalents à celui-là, lui-même étant compris (s'il n'existe pas d'élément d'interclassement équivalent, le traitement correspond à celui obtenu si les délimiteurs sont [. et .]). Par exemple, si o et ^ sont les membres d'une classe d'équivalence, alors [[=o=]], [[=^=]] et [o^] sont tous synonymes. Une classe d'équivalence ne peut pas être la borne d'une plage.

Dans une expression entre crochets, le nom d'une classe de caractères écrit entre [: et :] représente la liste de tous les caractères appartenant à cette classe. Les noms de classes de caractères standard sont alnum, alpha, blank, cntrl, digit, graph, lower, print, punct, space, upper, xdigit. Ils correspondent aux classes de caractère définies dans ctype(3). Une locale peut en fournir d'autres. Une classe de caractères ne peut pas être utilisée comme borne d'une plage.

Il existe deux cas spéciaux d'expressions entre crochets : les expressions entre crochets [[:<:]] et [[:>:]] sont des contraintes, qui établissent une correspondance avec des chaînes vides respectivement au début et à la fin d'un mot. Un mot est défini comme une séquence de caractères de mot qui n'est ni précédée ni suivie de caractères de mot. Un caractère de mot est un caractère alnum (comme défini par ctype(3)) ou un tiret bas. C'est une extension, compatible avec, mais non spécifiée dans POSIX 1003.2, et devant être utilisée avec précaution dans les logiciels conçus pour être portables sur d'autres systèmes. Les échappements de contraintes décrits ci-dessous sont généralement préférables (ils ne sont pas plus standard mais certainement plus simples à saisir).

9.7.3.3. Échappement d'expressions rationnelles

Les échappements sont des séquences spéciales débutant avec \ suivi d'un caractère alphanumérique. Il existe plusieurs sortes d'échappements : entrée de caractère, raccourci de classe, échappement de contraintes et références arrières. Un \ suivi d'un caractère alphanumérique mais ne constituant pas un échappement valide est illégal dans une ERA. Pour les ERE, il n'y pas d'échappement : en dehors d'une expression entre crochets, un \ suivi d'un caractère alphanumérique représnete simplement ce caractère (comme ordinaire) et, à l'intérieur d'une expression entre crochets, \ est un caractère ordinaire. (Ce dernier cas constitue l'incompatibilité réelle entre les ERE et les ERA).

Les échappements d'entrée de caractère existent pour faciliter la spécification de caractères non affichables et donc indésirables dans les ER. Ils sont présntés dans le Tableau 9.15, « Échappements de caractère dans les expressions rationnelles ».

Les échappements de raccourci de classe fournissent des raccourcis pour des classes de caractères communément utilisées. Ils sont présentés dans le Tableau 9.16, « Échappement de raccourcis de classes dans les expressions rationnelles ».

Un échappement de contrainte est une contrainte, fournissant une correspondance avec la chaîne vide si des conditions spécifiques sont rencontrées, écrit comme un échappement. Ils sont présentés dans le Tableau 9.17, « Échappements de contraintes dans les expressions rationnelles ».

Une référence arrière (\n) offre un correspondance avec la même chaîne que la sous-expression entre parenthèses précédente spécifiée par le nombre n (voir le Tableau 9.18, « Références arrières dans les expressions rationnelles »). Par exemple, ([bc])\1 peut correspondre à bb ou cc mais ni à bc ni à cb. La sous-expression doit précéder complètement la référence dans l'ER. Les sous-expressions sont numérotées dans l'ordre des parenthèses ouvrantes. Les parenthèses non capturantes ne définissent pas de sous-expressions.

[Note]

Note

Le symbole \ qui débute une séquence d'échappement doit être obligatoirement doublé pour saisir le motif comme une chaîne SQL constante. Par exemple :

'123' ~ E'^\\d{3}' true

Tableau 9.15. Échappements de caractère dans les expressions rationnelles

Échappement Description
\a caractère alerte (cloche), comme en C
\b effacement (backspace), comme en C
\B synonyme de \ pour aider à la réduction des doubles antislashs
\cX (où X est un caractère quelconque) le caractère dont les cinq bits de poids faible sont les mêmes que ceux de X et dont tous les autres bits sont à zéro
\e le caractère dont le nom de séquence d'interclassement est ESC, ou le caractère de valeur octale 033
\f retour chariot (form feed), comme en C
\n retour à la ligne (newline), comme en C
\r retour chariot (carriage return), comme en C
\t tabulation horizontale, comme en C
\uwxyz (où wxyz représente exactement quatre chiffres hexadécimaux) le caractère UTF16 (Unicode, 16 bits) U+wxyz dans l'ordre local des octets
\Ustuvwxyz (où stuvwxyz représente exactement huit chiffres hexadécimaux) réservé pour une extension, hypothétique, de l'Unicode vers le 32 bits
\v tabulation verticale, comme en C
\xhhh (où hhh représente toute séquence de chiffres hexadécimaux) le caractère dont la valeur hexadécimale est 0xhhh (un simple caractère, peu importe le nombre de chiffres hexadécimaux utilisés)
\0 le caractère dont la valeur est 0
\xy (où xy représente exactement deux chiffres octaux et qui n'est pas une référence arrière) le caractère dont la valeur octale est 0xy
\xyz (où xyz représente exactement trois chiffres octaux et qui n'est pas une référence arrière) le caractère dont la valeur octale est 0xyz

Les chiffres hexadécimaux sont 0-9, a-f et A-F. Les chiffres octaux sont 0-7.

Les échappements de caractères sont toujours pris comme des caractères ordinaires. Par exemple, \135 est ] en ASCII mais \135 ne termine pas une expression entre crochets.

Tableau 9.16. Échappement de raccourcis de classes dans les expressions rationnelles

Échappement Description
\d [[:digit:]]
\s [[:space:]]
\w [[:alnum:]_] (le tiret bas est inclus)
\D [^[:digit:]]
\S [^[:space:]]
\W [^[:alnum:]_] (le tiret bas est inclus)

Dans les expressions entre crochets, \d, \s, et \w perdent leurs crochets externes. \D, \S et \W ne sont pas autorisés. (Ainsi, par exemple, [a-c\d] est équivalent à [a-c[:digit:]]. Mais [a-c\D], qui est équivalent à [a-c^[:digit:]], est interdit).

Tableau 9.17. Échappements de contraintes dans les expressions rationnelles

Échappement Description
\A n'établit une correspondance qu'au début de la chaîne (voir la Section 9.7.3.5, « Règles de correspondance des expressions rationnelles » pour comprendre comment ceci diffère de ^)
\m n'établit une correspondance qu'au début d'un mot
\M n'établit une correspondance qu'à la fin d'un mot
\y n'établit de correspondance qu'au début ou à la fin d'un mot
\Y n'établit de correspondance qu'en dehors du début et de la fin d'un mot
\Z n'établit de correspondance qu'à la fin d'une chaîne (voir la Section 9.7.3.5, « Règles de correspondance des expressions rationnelles » pour comprendre comment ceci diffère de $)

Un mot est défini suivant la spécification établit par [[:<:]] et [[:>:]] ci-dessus. Les contraintes d'échappements sont interdites dans les expressions entre crochets.

Tableau 9.18. Références arrières dans les expressions rationnelles

Échappement Description
\m (où m est un chiffre différent de zéro) référence à la m-ième sous-expression
\mnn (où m est un chiffre différent de zéro et nn quelques chiffres supplémentaires, et la valeur décimale mnn n'est pas plus grande que le nombre de parenthèses fermantes capturantes vues jusque là) référence à la mnn-ième sous-expression

[Note]

Note

Il existe une ambiguïté historique inhérente entre les échappements de caractères en octal et les références. Cette ambiguïté est résolue par des heuristiques, comme montré ci-dessus. Un zéro en début de chaîne indique toujours un échappement octal. Un caractère seul différent de zéro et suivi d'un autre caractère est toujours pris comme une référence. Une séquence à plusieurs chiffres ne commençant pas avec un zéro est prise comme une référence si elle vient après une sous-expression convenable (c'est-à-dire que le nombre fait partie des numéros autorisés pour une référence). Dans le cas contraire, il est pris comme nombre octal.

9.7.3.4. Métasyntaxe des expressions rationnelles

En plus de la syntaxe principale décrite ci-dessus, il existe quelques formes spéciales et autres possibilités syntaxiques.

Normalement, le type d'ER considéré est déterminé par regex_flavor. Néanmoins, ce paramètre peut être surchargé par un préfixe directeur. Si une ER commence par ***:, le reste de l'ER est considéré comme une ERA, quelque soit la valeur de regex_flavor. Si une ER commence par ***=, le reste de l'ER est considéré comme une chaîne littérale, tous les caractères étant donc considérés ordinaires.

Une ERA peut débuter par des options intégrées : une séquence (?xyz) (où xyz correspond à un ou plusieurs caractères alphabétiques) spécifie les options affectant le reste de l'ER. Ces options surchargent toutes les options précédemment déterminées (incluant le type de l'ER et la sensibilité à la casse). Les lettres d'options disponibles sont indiquées dans le Tableau 9.19, « Lettres d'option intégrées à une ERA ».

Tableau 9.19. Lettres d'option intégrées à une ERA

Option Description
b le reste de l'ER est une ERB
c activation de la sensibilité à la casse (surcharge l'opérateur type)
e le reste de l'ER est une ERE
i désactivation de la sensibilité à la casse (voir la Section 9.7.3.5, « Règles de correspondance des expressions rationnelles ») (surcharge l'opérateur type)
m synonyme historique pour n
n activation de la sensibilité aux nouvelles lignes (voir la Section 9.7.3.5, « Règles de correspondance des expressions rationnelles »)
p activation de la sensibilité partielle aux nouvelles lignes (voir la Section 9.7.3.5, « Règles de correspondance des expressions rationnelles »)
q le reste de l'ER est une chaîne littérale (« entre guillemets »), composé uniquement de caractères ordinaires
s désactivation de la sensibilité aux nouvelles lignes (par défaut)
t syntaxe compacte (par défaut ; voir ci-dessous)
w activation de la sensibilité partielle aux nouvelles lignes inverse (« étrange ») (voir la Section 9.7.3.5, « Règles de correspondance des expressions rationnelles »)
x syntaxe étendue (voir ci-dessous)

Les options intégrées prennent effet à la ) terminant la séquence. Elles ne peuvent apparaître qu'au début d'une ERA (après le directeur ***: s'il y en a un).

En plus de la syntaxe habituelle d'une ER (compacte), dans laquelle tous les caractères ont une signification, il existe une syntaxe étendue, accessible en signifiant l'option intégrée x. Avec la syntaxe étendue, les caractères espace dans l'ER sont ignorés comme le sont tous les caractères entre un # et le retour-chariot qui suit (ou la fin de l'ER). Ceci permet de parapher et commenter une ER complexe. Il existe trois exceptions à cette règle de base :

  • un caractère espace ou # suivi d'un \ est retenu

  • un caractère espace ou # à l'intérieur d'une expression entre crochets est retenu

  • un caractère espace ou un commentaire ne peut pas apparaître dans les symboles multi-caractères, tels que (?:

À ce propos, les caractères espace sont l'espace, la tabulation, le retour chariot et tout caractère appartenant à la classe de caractère space.

Enfin, dans une ERA, à l'extérieur des expressions entre crochets, la séquence (?#ttt) (où ttt est tout texte ne contenant pas )) est un commentaire, totalement ignoré. Là encore, cela n'est pas permis entre les caractères des symboles multi-caractères comme (?:. De tels commentaires sont plus un artéfact historique qu'une fonctionnalité utile et leur utilisation est obsolète ; on utilisera plutôt la syntaxe étendue.

Aucune de ces extensions métasyntaxique n'est disponible si un directeur initial ***= indique que la saisie utilisateur doit être traitée comme une chaîne littérale plutôt que comme une ER.

9.7.3.5. Règles de correspondance des expressions rationnelles

Dans l'hypothèse où une ER peut correspondre à plusieurs sous-chaînes d'une chaîne donnée, l'ER correspond celle qui apparaît la première dans la chaîne. Si ER peut correspondre à plusieurs sous-chaînes à partir de ce point, c'est soit la correspondance la plus longue possible soit la correspondance la plus courte possible qui est retenue suivant que l'ER est gourmande ou non-gourmande (greedy/non-greedy).

La gourmandise d'une ER est déterminée par les règles suivantes :

  • la plupart des atomes, et toutes les contraintes, n'ont pas d'attribut de gourmandise (parce qu'ils ne peuvent, en aucune façon, établir de correspondance avec des quantités variables de texte) ;

  • l'ajout de parenthèses autour d'une ER ne change pas sa gourmandise ;

  • un atome quantifié avec un quantificateur à répétition fixe ({m} ou {m}?) a la même gourmandise (éventuellement aucune) que l'atome lui-même ;

  • un atome quantifié avec d'autres quantificateurs standard (dont {m,n} avec m égal à n) est gourmand (préfère la plus grande correspondance) ;

  • un atome quantifié avec un quantificateur non gourmand (dont {m,n}? avec m égal à n) n'est pas gourmand (préfère la plus courte correspondance) ;

  • une branche -- c'est-à-dire une ER dépourvue d'opérateur | au sommet -- est aussi gourmande que le premier atome quantifié qu'elle contient qui possède un attribut de gourmandise ;

  • une ER constituée au minimum de deux branches connectées par l'opérateur | est toujours gourmande.

Les règles ci-dessus associent les attributs de gourmandise non seulement avec les atomes quantifiés individuels, mais aussi avec les branches et les ER complètes qui contiennent des atomes quantifiés. Cela signifie que la correspondance est établie de sorte que la branche, ou l'ER complète, corresponde à la sous-chaîne la plus longue ou la plus courte possible comme un tout. Une fois la longueur de la correspondance complète déterminée, la partie de cette correspondance qui établit une correspondance avec une sous-expression particulière est déterminée sur la base de l'attribut de gourmandise de cette sous-expression, priorité étant donnée aux sous-expressions commençant le plus tôt dans l'ER.

Exemple de signification de tout cela :

SELECT SUBSTRING('XY1234Z', 'Y*([0-9]{1,3})');
Resultat : 123
SELECT SUBSTRING('XY1234Z', 'Y*?([0-9]{1,3})');
Resultat : 1

Dans le premier cas, l'ER dans son intégralité est gourmande parce que Y* est gourmand. Elle peut correspondre au début de Y et établlit une correspondance avec la chaîne la plus longue à partir de là, soit Y123. La sortie reprend la partie entre parenthèses, soit 123. Dans le second cas, l'ER dans son ensemble n'est pas gourmande car Y*? ne l'est pas. Elle peut correspondre au début de Y et établit une correspondance avec la chaîne la plus courte à partir de là, soit Y1. La sous-expression [0-9]{1,3} est gourmande mais elle ne peut pas changer la décision sur la longueur totale de la correspondance ; elle ne peut donc correspondre qu'à 1.

En résumé, quand une ER contient à la fois des sous-expressions gourmandes et non gourmandes, la longueur de la correspondance totale est soit aussi longue que possible soit aussi courte que possible, en fonction de l'attribut affecté à l'ER complète. Les attributs assignés aux sous-expressions permettent uniquement de déterminer la partie de la correspondance qu'elles peuvent incorporer les unes par rapport aux autres.

Les quantificateurs {1,1} et {1,1}? peuvent être utilisés pour forcer, respectivement, la préférence la plus longue (gourmandise) ou la plus courte (retenue), sur une sous-expression ou une ER complète.

Les longueurs de correspondance sont mesurés en caractères, et non en éléments d'interclassement. Une chaîne vide est considérée plus grande que pas de correspondance du tout. Par exemple : bb* correspond aux trois caractères du milieu de abbbc ; (week|wee)(night|knights) correspond aux dix caractères de weeknights ; lorsque une correspondance est recherchée entre (.*).* et abc, la sous-expression entre parenthèses correspond aux trois caractères ; et lorsqu'une correspondance est recherchée entre (a*)* et bc, à la fois l'ER et la sous-expression entre parenthèses correspondent à une chaîne vide.

Lorsqu'il est précisé que la recherche de correspondance ne tient pas compte de la casse, cela revient à considérer que toutes les distinctions de casse ont disparu de l'alphabet. Quand un caractère alphabétique, pour lequel existent différentes casses, apparaît comme un caractère ordinaire en dehors d'une expression entre crochets, il est en fait transformé en une expression entre crochets contenant les deux casses, c'est-à-dire que x devient [xX]. Quand il apparaît dans une expression entre crochets, toutes les transformations de casse sont ajoutées à l'expression entre crochets, c'est-à-dire que [x] devient [xX] et que [^x] devient [^xX].

Si la sensibilité aux retours chariots est précisée, . et les expressions entre crochets utilisant ^ n'établissent jamais de correspondance avec le caractère de retour à la ligne (de cette façon, les correspondances ne franchissent jamais les retours chariots sauf si l'ER l'explicite), et ^ et $ établissent une correspondance avec la chaîne vide, respectivement après et avant un retour chariot, en plus d'établir une correspondance respectivement au début et à la fin de la chaîne. Mais les échappements d'ERA \A et \Z n'établissent toujours de correspondance qu'au début ou à la fin de la chaîne.

Si une sensibilité partielle aux retours chariot est indiquée, cela affecte . et les expressions entre crochets, comme avec la sensibilité aux retours chariot, mais pas ^ et $.

Si une sensibilité partielle inverse aux retours chariot est indiquée, cela affecte ^ et $, comme avec la sensibilité aux retours chariot, mais pas . et les sous-expressions. Ceci n'est pas très utile mais est toutefois fourni pour des raisons de symétrie.

9.7.3.6. Limites et compatibilité

Aucune limite particulière n'est imposée sur la longueur des ER dans cette implantation. Néanmoins, les programmes prévus pour être portables ne devraient pas employer d'ER de plus de 256 octets car une implantation POSIX peut refuser d'accepter de telles ER.

La seule fonctionnalité des ERA qui soit incompatible avec les ERE POSIX est le maintien de la signification spéciale de \ dans les expressions entre crochets. Toutes les autres fonctionnalités ERA utilisent une syntaxe interdite, à effets indéfinis ou non spécifiés dans les ERE POSIX ; la syntaxe *** des directeurs ne figure pas dans la syntaxe POSIX pour les ERB et les ERE.

Un grand nombre d'extensions ERA sont empruntées de Perl mais certaines ont été modifiées et quelques extensions Perl ne sont pas présentes. Les incompatibilités incluent \b, \B, le manque de traitement spécial pour le retour à la ligne en fin de chaîne, l'ajout d'expressions entre crochets aux expressions affectées par les correspondances avec retour à la ligne, les restrictions sur les parenthèses et les références dans les contraintes et la sémantique de correspondance chaînes les plus longues/les plus courtes (au lieu de la première rencontrée).

Deux incompatibilités importantes existent entre les syntaxes ERA et ERE reconnues par les versions antérieures à PostgreSQL™ 7.4 :

  • dans les ERA, \ suivi d'un caractère alphanumérique est soit un échappement soit une erreur alors que dans les versions précédentes, c'était simplement un autre moyen d'écrire un caractère alphanumérique. Ceci ne devrait pas poser trop de problèmes car il n'y avait aucune raison d'écrire une telle séquence dans les versions plus anciennes ;

  • dans les ERA, \ reste un caractère spécial à l'intérieur de [], donc un \ à l'intérieur d'une expression entre crochets doit être écrit \\.

Même si ces différences ne posent pas de problèmes pour la plupart des applications, il est possible de les éviter en initialisant regex_flavor à extended.

9.7.3.7. Expressions rationnelles élémentaires

Les ERB diffèrent des ERE par plusieurs aspects. |, + et ? sont des caractères ordinaires et il n'existe pas d'équivalent pour leur fonctionnalité. Les délimiteurs de frontières sont \{ et \}, avec { et } étant eux-même des caractères ordinaires. Les parenthèses pour les sous-expressions imbriquées sont \( et \), avec ( et ) eux-mêmes des caractères ordinaires. ^ est un caractère ordinaire sauf au début d'une ER ou au début d'une sous-expression entre parenthèses, $ est un caractère ordinaire sauf à la fin d'une ER ou à la fin d'une sous-expression entre parenthèses et * est un caractère ordinaire s'il apparaît au début d'une ER ou au début d'une sous-expression entre parenthèses (après un possible ^). Enfin, les références arrières à un chiffre sont disponibles, et \< et \> sont des synonymes pour respectivement [[:<:]] et [[:>:]] ; aucun autre échappement n'est disponible.