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. En dehors des opérateurs basiques du style « est-ce que cette chaîne correspond à ce modèle ? », les fonctions sont disponibles pour extraire ou remplacer des sous-chaînes correspondantes ou pour diviser une chaîne aux emplacements correspondants.
Si un besoin de correspondances de motif va au-delà, il faut considérer l'écriture d'une fonction en Perl ou Tcl.
chaîne LIKE motif [ESCAPE caractère d'échappement] chaîne NOT LIKE motif [ESCAPE caractère d'échappement]
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. Du coup, 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 correspondance avec 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, voir Section 4.1.2.1, « Constantes de chaînes »). Ainsi, 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é pour correspondre à un antislash).
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™.
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 se rapproche de 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 en désaccord avec les pratiques habituelles des expressions rationnelles où le modèle peut se situer n'importe où dans la chaîne. Tout comme LIKE, SIMILAR TO utilise _ et % comme caractères joker représentant 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 :
| représente une alternative (une des deux alternatives) ;
* représente la répétition des éléments précédents, 0 ou plusieurs fois ;
+ représente 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 opérateurs de 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 indiqué 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, avec #" délimitant la chaîne en retour :
substring('foobar' from '%#"o_b#"%' for '#') oob substring('foobar' from '#"o_b#"%' for '#') NULL
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
Le langage modèle POSIX est décrit avec plus de détail ci-dessous.
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 qui correspond 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). Les autres options supportées sont décrites dans Tableau 9.19, « Lettres d'option intégrées à une ERA ».
Quelques exemples :
regexp_replace('foobarbaz', 'b..', 'X') fooXbaz regexp_replace('foobarbaz', 'b..', 'X', 'g') fooXX regexp_replace('foobarbaz', 'b(..)', E'X\\1Y', 'g') fooXarYXazY
La fonction regexp_matches renvoie toutes les sous-chaînes capturées résultant de la correspondance avec une expression rationnelle POSIX. Elle a la syntaxe : regexp_matches(chaine, modele [, options ]). S'il n'y a pas de correspondance avec modele, la fonction ne renvoie aucune ligne. S'il y a une correspondance, la fonction renvoie un tableau de texte dont l'élément n est la sous-chaîne en correspondance avec la n-ième sous-expression entre parenthèses du modèle (sans compter les parenthèses « non capturantes » ; voir ci-dessous pour les détails). Si le modèle ne contient aucune sous-expression entre parenthèses, le résultat est un tableau texte à un seul élément représentant la sous-chaîne correspondant au modèle complet. Le paramètre options est une chaîne optionnelle contenant zéro ou plus options d'une lettre, modifiant ainsi le comportement de la fonction. L'option g indique que la fonction trouve chaque correspondance dans la chaîne, pas seulement la première, et renvoie une ligne pour chaque correspondance. Les autres options supportées sont décrites dans Tableau 9.19, « Lettres d'option intégrées à une ERA ».
Quelques exemples :
SELECT regexp_matches('foobarbequebaz', '(bar)(beque)'); regexp_matches ---------------- {bar,beque} (1 row) SELECT regexp_matches('foobarbequebazilbarfbonk', '(b[^b]+)(b[^b]+)', 'g'); regexp_matches ---------------- {bar,beque} {bazil,barf} (2 rows) SELECT regexp_matches('foobarbequebaz', 'barbeque'); regexp_matches ---------------- {barbeque} (1 row)
La fonction regexp_split_to_table divise une chaîne en utilisant une expression rationnelle POSIX comme délimiteur. Elle a la syntaxe suivante : regexp_split_to_table(chaine, modele [, options ]). S'il n'y a pas de correspondance avec le modele, la fonction renvoie la chaine. S'il y a au moins une correspondance, pour chaque correspondance, elle renvoie le texte à partir de la fin de la dernière correspondance (ou le début de la chaîne) jusqu'au début de la correspondance. Quand il ne reste plus de correspondance, elle renvoie le texte depuis la fin de la dernière correspondance jusqu'à la fin de la chaîne. Le paramètre options est une chaîne optionelle contenant zéro ou plus options d'un caractère, modifiant ainsi le comportement de la fonction. regexp_split_to_table supporte les options décrites dans Tableau 9.19, « Lettres d'option intégrées à une ERA ».
La fonction regexp_split_to_array se comporte de la même façon que regexp_split_to_table, sauf que regexp_split_to_array renvoie son résultat en tant que tableau de text. Elle a comme syntaxe regexp_split_to_array(chaine, modele [, options ]). Les paramètres sont les mêmes que pour regexp_split_to_table.
Quelques exemples :
SELECT foo FROM regexp_split_to_table('the quick brown fox jumped over the lazy dog', E'\\s+') AS foo; foo -------- the quick brown fox jumped over the lazy dog (9 rows) SELECT regexp_split_to_array('the quick brown fox jumped over the lazy dog', E'\\s+'); regexp_split_to_array ------------------------------------------------ {the,quick,brown,fox,jumped,over,the,lazy,dog} (1 row) SELECT foo FROM regexp_split_to_table('the quick brown fox', E'\\s*') AS foo; foo ----- t h e q u i c k b r o w n f o x (16 rows)
Comme le montre le dernier exemple, les fonctions de division des expressions rationnelles ignorent les correspondances de longueur nulle qui surviennent au début ou à la fin de la chaîne ou immédiatement après une correspondance. C'est contraire à la définition stricte de la correspondance des expressions rationnelles implantée par regexp_matches, mais c'est habituellement le comportement le plus pratique. Les autres systèmes comme Perl utilisent des définitions similaires.
Les expressions rationnelles de PostgreSQL™ sont implantées à l'aide d'un paquetage écrit par Henry Spencer. Une grande partie de la description des expressions rationnelles ci-dessous est une copie intégrale de son manuel.
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 du fait de 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.
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 18, 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 quantificateur unique. Sans quantificateur, il établit une correspondance avec l'atome. Avec un quantificateur, 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 quantificateurs 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 et 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ère de 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 | où x est un caractère unique sans signification, établit une correspondance avec ce caractère |
Une ER ne peut pas se terminer par \.
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 (voir Section 4.1.2.1, « Constantes de chaînes »).
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.
Un quantificateur ne peut pas immédiatement suivre un autre quantificateur, autrement dit ** est invalide. 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.
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 premier 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'interclassement. 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.
PostgreSQL™ n'a pas, à ce jour, d'éléments d'interclassement multi-caractères. L'information portée 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 compris. (En l'absence d'élément d'interclassement équivalent, le traitement correspond à celui obtenu avec les délimiteurs [. 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 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ères 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).
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étro-références. Un \ suivi d'un caractère alphanumérique qui ne constitue 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ésente simplement ce caractère (comme ordinaire) et, à l'intérieur d'une expression entre crochets, \ est un caractère ordinaire. (C'est dans ce dernier cas que se situe réellement l'incompatibilité entre les ERE et les ERA.)
Les échappements de caractère (character-entry escapes) permettent d'indiquer des caractères non affichables et donc indésirables dans les ER. Ils sont présentés dans le Tableau 9.15, « Échappements de caractère dans les expressions rationnelles ».
Les échappements de raccourci de classe (class-shorthand escapes) fournissent des raccourcis pour certaines 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 (constraint escape) est une contrainte, qui correspond à la chaîne vide sous certaines conditions, écrite comme un échappement. Ces échappements sont présentés dans le Tableau 9.17, « Échappements de contrainte dans les expressions rationnelles ».
Une rétro-référence (back reference) (\n) correspond à la même chaîne que la sous-expression entre parenthèses précédente indiquée par le nombre n (voir le Tableau 9.18, « Rétro-références 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.
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 éviter les doublements d'antislash |
\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 n'est pas une rétro-référence) le caractère dont la valeur octale est 0xy |
\xyz | (où xyz représente exactement trois chiffres octaux et n'est pas une rétro-référence) 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ère 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 et \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 contrainte dans les expressions rationnelles
Échappement | Description |
---|---|
\A | n'établit la 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 la différence avec ^) |
\m | n'établit la correspondance qu'au début d'un mot |
\M | n'établit la correspondance qu'à la fin d'un mot |
\y | n'établit la correspondance qu'au début ou à la fin d'un mot |
\Y | n'établit la correspondance qu'en dehors du début et de la fin d'un mot |
\Z | n'établit la correspondance qu'à la fin d'une chaîne (voir la Section 9.7.3.5, « Règles de correspondance des expressions rationnelles » pour comprendre la différence avec $) |
Un mot est défini selon suivant la spécification de [[:<:]] et [[:>:]] donnée ci-dessus. Les échappement de contrainte sont interdits dans les expressions entre crochets.
Tableau 9.18. Rétro-références 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 |
Une ambiguïté persiste entre les échappements de caractère octal et les rétro-références. Cette ambiguïté est résolue par les heuristiques suivantes, 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, qui n'est pas suivi d'un autre caractère, est toujours pris comme une rétro-référence. Une séquence à plusieurs chiffres qui ne débute pas par zéro est prise comme une référence si elle suit une sous-expression utilisable (c'est-à-dire que le nombre est dans la plage autorisée pour les rétro-références). Dans le cas contraire, il est pris comme nombre octal.
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 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 (dont 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 inverse aux nouvelles lignes (« é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 ) qui termine 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 mettre en paragraphe et de 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
caractère espace et commentaires ne peuvent pas apparaître dans les symboles multi-caractères, tels que (?:
Pour cela, 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, en dehors d'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 artefact historique qu'une fonctionnalité utile et leur utilisation est obsolète ; on utilise 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.
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 l'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 selon 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. Il peut établir une correspondance qui débute à Y et correspondre à 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. Il peut établir une correspondance qui débute à Y et correspond à 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.
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 à 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.
Les ERB diffèrent des ERE par plusieurs aspects. Dans les BRE, |, + 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 \), ( et ) restent 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étro-références à un chiffre sont disponibles, et \< et \> sont des synonymes pour respectivement [[:<:]] et [[:>:]] ; aucun autre échappement n'est disponible dans les BRE.