PostgreSQLLa base de données la plus sophistiquée au monde.
Documentation PostgreSQL 12.22 » Langage SQL » Fonctions et opérateurs » Correspondance de motif

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. 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.

Astuce

Si un besoin de correspondances de motif va au-delà, il faut considérer l'écriture d'une fonction en Perl ou Tcl.

Attention

Alors que la plupart des recherches d'expression rationnelle sont exécutées très rapidement, les expressions rationnelles peuvent être écrites de telle façon que leur traitement prendra beaucoup de temps et de mémoire. Faites attention si vous acceptez des motifs d'expression rationnelle de source inconnue. Si vous devez le faire, il est conseillé d'imposer une durée maximale pour l'exécution d'une requête.

Les recherches utilisant des motifs SIMILAR TO ont le même souci de sécurité, car SIMILAR TO fournit en gros les mêmes possibilités que les expressions rationnelles POSIX.

Les recherches LIKE, bien plus simples que les deux autres options de recherches, sont plus sûres avec des sources potentiellement hostiles.

Les opérateurs de correspondance de motif des trois types ne supportent pas les collationnements non déterministes. Si nécessaire, appliquez un collationnement différent sur l'expression pour contourner cette limitation.

9.7.1. LIKE

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 pour cent 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 pour cent (%) à 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 commencer et finir avec un signe pour cent.

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 une correspondance avec le caractère d'échappement lui-même, on écrit deux fois ce caractère.

Note

Si vous avez désactivé standard_conforming_strings, tout antislash écrit dans une chaîne de caractères devra être doublé. Voir Section 4.1.2.1 pour plus d'informations.

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. Vous pouvez voir ces noms d'opérateur dans la sortie EXPLAIN et à des endroits similaires car l'optimiseur traduit LIKE et autres avec ces opérateurs.

Les phrases LIKE, ILIKE, NOT LIKE et NOT ILIKE sont habituellement traitées comme des opérateurs dans la syntaxe PostgreSQL ; par exemple, elles peuvent être utilisées dans des constructions expression operateur ANY (sous-requete), bien qu'une clause ESCAPE ne peut pas être inclus ici. Dans certains cas obscurs, il pourrait être nécessaire d'utiliser les noms d'opérateur sous-jacents à la place.

Il existe aussi un opérateur préfixe ^@ et la fonction correspondante starts_with qui couvrent les cas où seule la recherche de début de chaîne est nécessaire.

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 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étacaractè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 ;

  • ? dénote une répétition du précédent élément zéro ou une fois ;

  • {m} dénote une répétition du précédent élément exactement m fois ;

  • {m,} dénote une répétition du précédent élément m ou plusieurs fois ;

  • {m,n} dénote une répétition du précédent élément au moins m et au plus n 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.

Notez que le point (.) n'est pas un métacaractère pour SIMILAR TO.

Comme avec LIKE, un antislash désactive la signification spéciale de tous les métacaractè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 fournit une extraction d'une sous-chaîne correspondant au motif d'expression rationnelle SQL. Cette fonction peut être écrite en suivant la syntaxe SQL99 :

substring(string from pattern for escape-character)

ou sous la forme d'une fonction simple à trois arguments :

substring(string, pattern, escape-character)

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 pour laquelle la sous-chaîne de données correspondante est intéressante, 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 séparateurs est renvoyé quand il y a correspondance.

Les séparateurs doubles guillemets d'échappement divisent en fait le motif de la sous-chaîne en trois expressions rationnelles indépendantes ; par exemple, une barre verticale (|) dans une des trois sections affecte seulement cette section. De plus, la première et la troisième de ces expressions rationnelles sont définies pour correspondre à la plus petite quantité possible de texte, et non pas à la plus grande, quand il n'y a aucune ambiguïté sur la correspondance entre la chaîne de données et le motif. (Dans la parlance POSIX, on dit que la première et la troisième expressions rationnelles sont forcées à ne pas être greedy.)

Comme extension au standard SQL, PostgreSQL permet qu'il y ait juste un séparateur doubles guillemets d'échappement, auquel cas la troisième expression rationnelle est comprise comme vide ; ou aucun séparateur, auquel cas les première et troisième expressions rationnelles sont comprises comme vides.

Quelques exemples, avec #" délimitant la chaîne en retour :

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

9.7.3. Expressions rationnelles POSIX

Le Tableau 9.15 liste les opérateurs disponibles pour la correspondance de motifs à partir d'expressions rationnelles POSIX.

Tableau 9.15. Opérateurs de correspondance des expressions rationnelles

OpérateurDescriptionExemple
~ 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 la 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 niè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 \\ pour placer un antislash littéral dans le texte de remplacement. 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 options supportées (sauf g) sont décrites dans Tableau 9.23.

Quelques exemples :

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

La fonction regexp_match renvoie un tableau de texte constitué de la ou des sous-chaînes capturées depuis la première correspondance d'une expression régulière POSIX jusqu'à une chaîne. Elle a la syntaxe regexp_match(string, pattern [, flags ]). S'il n'y a pas de correspondance, le résultat est NULL. S'il y a une correspondance, et que pattern ne contient pas d'expression entre parenthèses, alors le résultat est un tableau contenant un seul élément texte, contenant la sous-chaîne correspondant à la totalité du motif. S'il y a une correspondance, et quepattern contient des expressions entre parenthèses, alors le résultat est un tableau de texte dont le nième élément est la sous-chaîne correspondant à la nième expression entre parenthèses du motif (sans compter les parenthèses « non capturantes » ; voir ci-dessous pour plus de détails). Le paramètre flags est une chaîne de texte facultative contenant zéro ou plus drapeaux d'une lettre qui change le comportement de la fonction. Les drapeaux supportés sont décrit dans Tableau 9.23.

Quelques exemples :

SELECT regexp_match('foobarbequebaz', 'bar.*que');
 regexp_match
--------------
 {barbeque}
(1 row)

SELECT regexp_match('foobarbequebaz', '(bar)(beque)');
 regexp_match
--------------
 {bar,beque}
(1 row)

Dans le cas général où vous voulez uniquement la totalité de la chaîne correspondante ou NULL s'il n'y a pas de correspondance, écrivez quelque chose comme

SELECT (regexp_match('foobarbequebaz', 'bar.*que'))[1];
 regexp_match
--------------
 barbeque
(1 row)

La fonction regexp_matches renvoie un ensemble de tableaux de texte de la ou les chaînes capturées résultant de la correspondance d'un motif d'expression régulière POSIX vers une chaîne. Elle a la même syntaxe que regexp_match. Cette fonction ne retourne pas de ligne s'il n'y a pas de correspondance, une ligne s'il y a une correspondance et que le drapeau g n'est pas positionné, ou N lignes s'il y a N correspondances et que le drapeau g est positionné. Chaque ligne retournée est un tableau de texte contenant la totalité de la sous-chaîne correspondante ou la sous-chaîne correspondant à la sous-expression entre parenthèses du motif, tout comme décrit ci-dessus pour regexp_match. regexp_matches accepte tous les drapeaux montrés dans Tableau 9.23, plus le drapeau g qui demande à retourner toutes les correspondances, pas uniquement la première.

Quelques exemples :

 SELECT regexp_matches('foo', 'not there');
 regexp_matches
----------------
(0 rows)

SELECT regexp_matches('foobarbequebazilbarfbonk', '(b[^b]+)(b[^b]+)', 'g');
 regexp_matches
----------------
 {bar,beque}
 {bazil,barf}
(2 rows)

Astuce

Dans la plupart des cas, regexp_matches() devrait être utilisée avec le drapeau g, puisque si vous ne voulez que la première occurrence, il est plus simple et plus efficace d'utiliser regexp_match(). Toutefois, regexp_match() n'existe que dans les versions 10 et supérieures de PostgreSQL. Quand vous travaillez avec des versions plus anciennes, une astuce habituelle est de placer un appel à regexp_matches() dans un sous-select, par exemple :

SELECT col1, (SELECT regexp_matches(col2, '(bar)(beque)')) FROM tab;
 

Cela renvoie un tableau de texte s'il y a une correspondance ou NULL sinon, tout comme regexp_match() le ferait. Sans le sous-select, cette requête ne produirait pas de sortie du tout pour les lignes de la table ne contenant pas de correspondance, ce qui n'est généralement pas le comportement voulu.

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 optionnelle 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.23.

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 jumps over the lazy dog', '\s+') AS foo;
foo
--------
the
quick
brown
fox
jumps
over
the
lazy
dog
(9 rows)

SELECT regexp_split_to_array('the quick brown fox jumps over the lazy dog', '\s+');
regexp_split_to_array
------------------------------------------------
{the,quick,brown,fox,jumps,over,the,lazy,dog}
(1 row)

SELECT foo FROM regexp_split_to_table('the quick brown fox', '\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_match et regexp_matches, mais c'est habituellement le comportement le plus pratique. Les autres systèmes comme Perl utilisent des définitions similaires.

9.7.3.1. Détails des expressions rationnelles

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.

Note

PostgreSQL présume toujours au départ qu'une expression rationnelle suit les règles ERA. Néanmoins, les règles ERE et BRE (plus limitées) peuvent être choisies en ajoutant au début une option d'imbrication sur le motif de l'ER, comme décrit dans Section 9.7.3.4. Cela peut être utile pour la compatibilité avec les applications qui s'attendent à suivre exactement les règles POSIX.

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.16. Les quantificateurs possibles et leurs significations sont disponibles dans le Tableau 9.17.

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.18 ; quelques contraintes supplémentaires sont décrites plus loin.

Tableau 9.16. Atomes d'expressions rationnelles

AtomeDescription
(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 pour plus de détails)
\k (où k n'est pas un caractère alphanumé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 (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 un antislash (\).

Note

Si vous avez désactivé standard_conforming_strings, tout antislash écrit dans une chaîne de caractères devra être doublé. Voir Section 4.1.2.1 pour plus d'informations.

Tableau 9.17. quantificateur d'expressions rationnelles

quantificateurCorrespondance
* 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êmes 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 pour plus de détails.

Note

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.18. Contraintes des expressions rationnelles

ContrainteDescription
^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)
(?<=re) positive lookbehind (recherche arrière positive) établit une correspondance avec tout point où une sous-chaîne correspond à re finit (uniquement pour les ERA)
(?<!re) negative lookbehind (recherche arrière négative) correspond à tout point où aucune sous-chaîne ne correspond à re finit (uniquement ERA)

Les contraintes « lookahead » et « lookbehind » ne doivent pas contenir de références arrières (voir la Section 9.7.3.3), 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 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 multicaractè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

PostgreSQL n'a pas, à ce jour, d'éléments d'interclassement multicaractè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. Une classe de caractères ne peut pas être utilisé comme point final d'un intervalle. Le standard POSIX définit les noms suivants de classe de caractères : alnum (lettres et chiffres), alpha (lettres), blank (espace et tabulation), cntrl (caractères de contrôle), digit (chiffres), graph (caractères affichables sauf l'espace), lower (lettres en minuscule), print (caractères affichables avec l'espace), punct (ponctuation), space (tout espace blanc), upper (lettres en majuscules) et xdigit (chiffres hexadécimaux). Le comportement de classes de caractères standards est généralement cohérent parmi les différentes plateformes en ce qui concerne les ensembles ASCII 7 bits. Qu'un caractère non-ASCII soit considéré comme appartenant à une de ces classes dépend du collationnement utilisé pour la fonction ou l'opérateur d'expression rationnelle (voir Section 23.2), ou par défaut à la configuration du LC_CTYPE de la base de données (voir Section 23.1). La classification des caractères non-ASCII peut varier entre les plateformes même dans des locales nommées de façon similaire. (La locale C ne considère jamais les caractères non-ASCII comme appartenant à une de ces classes.) En plus de ces classes de caractères standards, PostgreSQL définit la classe de caractères ASCII, contenant exactement l'ensemble ASCII 7 bits.

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 la classe de caractères POSIX décrite ci-dessus) 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étroré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.19.

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.20.

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.21.

Une rétroré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.22). 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.

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

ÉchappementDescription
\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 dont la valeur hexadécimale est 0xwxyz
\Ustuvwxyz (où stuvwxyz représente exactement huit chiffres hexadécimaux) le caractère dont la valeur hexadécimale est 0xstuvwxyz
\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étroré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étroré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 numériques de saisie de caractères spécifiant des valeurs hors de l'intervalle ASCII (0-127) ont des significations dépendant de l'encodage de la base de données. Quand l'encodage est UTF-8, les valeurs d'échappement sont équivalents aux codes Unicode. Par exemple, \u1234 correspond au caractère U+1234. Pour d'autres encodages multioctets, les échappements de saisie de caractères spécifient uniquement la concaténation des valeurs d'octet pour le caractère. Si la valeur d'échappement ne correspond pas à un caractère légal dans l'encodage de la base de données, aucune erreur ne sera levée, mais cela ne correspondra à aucune donnée.

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.20. Échappement de raccourcis de classes dans les expressions rationnelles

ÉchappementDescription
\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, [a-c\d] est équivalent à [a-c[:digit:]]. Mais [a-c\D], qui est équivalent à [a-c^[:digit:]], est interdit.)

Tableau 9.21. Échappements de contrainte dans les expressions rationnelles

ÉchappementDescription
\A n'établit la correspondance qu'au début de la chaîne (voir la Section 9.7.3.5 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 pour comprendre la différence avec $)

Un mot est défini selon suivant la spécification de [[:<:]] et [[:>:]] donnée ci-dessus. Les échappements de contrainte sont interdits dans les expressions entre crochets.

Tableau 9.22. Rétroréférences dans les expressions rationnelles

ÉchappementDescription
\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

Une ambiguïté persiste entre les échappements de caractère octal et les rétroré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étroré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étroréférences). 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.

Une ER peut commencer avec un des deux préfixes director spéciaux. Si une ER commence par ***:, le reste de l'ER est considéré comme une ERA. (Ceci n'a normalement aucun effet dans PostgreSQL, car les ER sont supposées être des ERA, mais il a un effet si le mode ERE ou BRE a été spécifié par le paramètre flags à une fonction d'expression rationnelle.) 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 commencer 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 -- en particulier, elles peuvent surcharger le comportement sur la sensibilité à la casse d'un opérateur d'une ER ou le paramètre flags vers une fonction d'expression rationnelle. Les lettres d'options disponibles sont indiquées dans le Tableau 9.23. Notez que ces mêmes lettres d'option sont utilisées dans les paramètres flags des fonctions d'expressions rationnelles.

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

OptionDescription
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) (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)
p activation de la sensibilité partielle aux nouvelles lignes (voir la Section 9.7.3.5)
q le reste de l'ER est une chaîne littérale (« entre guillemets »), composée 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)
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 multicaractè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 multicaractè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étasyntaxiques 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 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 et 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})');
Résultat : 123
SELECT SUBSTRING('XY1234Z', 'Y*?([0-9]{1,3})');
Résultat : 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. Ceci est utile quand vous avez besoin que l'expression complète ait une gourmandise différente de celle déduite de son élément. Par exemple, supposons que nous essayons de séparer une chaîne contenant certains chiffres en les chiffres et les parties avant et après. Nous pourrions le faire ainsi :

SELECT regexp_match('abc01234xyz', '(.*)(\d+)(.*)');
Résultat : {abc0123,4,xyz}
  

Cela ne fonctionne pas : le premier .* est tellement gourmand qu'il « mange » tout ce qu'il peut, laissant \d+ correspondre à la dernière place possible, à savoir le dernier chiffre. Nous pouvons essayer de corriger cela en lui demandant un peu de retenue :

SELECT regexp_match('abc01234xyz', '(.*?)(\d+)(.*)');
Résultat : {abc,0,""}
  

Ceci ne fonctionne pas plus parce que, maintenant, l'expression entière se retient fortement et, du coup, elle termine la correspondance dès que possible. Nous obtenons ce que nous voulons en forçant l'expression entière à être gourmande :

SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}');
Résultat : {abc,01234,xyz}
  

Contrôler la gourmandise de l'expression séparément de ses composants donne une plus grande flexibilité dans la gestion des motifs à longueur variable.

Lors de la décision de ce qu'est une correspondance longue ou courte, les longueurs de correspondance sont mesurées en caractères et non pas en éléments d'interclassement. Une chaîne vide est considérée comme 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 ; lorsqu'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 chariot 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 chariot, 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 à 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 arrière dans les contraintes lookahead/lookbehind 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 \\.

9.7.3.7. Expressions rationnelles élémentaires

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êmes 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étroréférences à un chiffre sont disponibles, et \< et \> sont des synonymes pour respectivement [[:<:]] et [[:>:]] ; aucun autre échappement n'est disponible dans les BRE.

9.7.3.8. Différences avec XQuery (LIKE_REGEX)

Depuis SQL:2008, le standard SQL inclut un opérateur LIKE_REGEX qui réalise de la correspondance de motif suivant le standard des expressions rationnelles XQuery. PostgreSQL ne dispose pas encore de cet opérateur, mais vous pouvez obtenir un comportement très similaire en utilisant la fonction regexp_match(), car les expressions rationnelles XQuery sont très proches de la syntaxe ERA décrite ci-dessus.

Les différences notables entre la fonctionnalité existante d'expressions rationnelles basées sur POSIX et les expressions rationnelles XQuery incluent :

  • la soustraction de classe de caractère XQuery n'est pas supportée. Un exemple de cette fonctionnalité est l'utilisation de l'expression suivante pour faire une correspondance avec seulement les consommes anglaises : [a-z-[aeiou]].

  • les raccourcis de classes de caractère XQuery \c, \C, \i et \I ne sont pas supportés.

  • les éléments de classe de caractères XQuery utilisant \p{UnicodeProperty} ou l'inverse \P{UnicodeProperty} ne sont pas supportés.

  • POSIX interprète les classes de caractère telles que \w (voir Tableau 9.20) suivant la locale prévalente (que vous pouvez contrôler en attachant une clause COLLATE à l'opérateur ou à la fonction. XQuery spécifie ces classes par référence aux propriétés des caractères Unicode, donc le comportement équivalent est obtenu seulement avec une locale qui suit les règles Unicode.

  • Le standard SQL (pas XQuery lui-même) tente d'accueillir un plus grand nombre de variantes de « newline » que ne le fait POSIX. Les options de correspondance pour les retours chariot décrites ci-dessus considèrent seulement ASCII NL ASCII NL (\n) comme étant un retour chariot, mais SQL pourrait avoir traité CR (\r), CRLF (\r\n) (un retour chariot provenant de Windows) et certains caractères Unicode comme LINE SEPARATOR (U+2028) comme des retours chariots eux aussi. De plus, . et \s devraient compter \r\n comme un caractère et non pas deux d'après SQL.

  • Des échappements de caractères décrits dans Tableau 9.19, XQuery supporte seulement \n, \r et \t.

  • XQuery ne supporte pas la syntaxe [:name:] pour les classes de caractères dans des expressions à crochets.

  • XQuery n'a pas de contraintes avant et arrière, ainsi que d'échappements de contraintes décrits dans Tableau 9.21.

  • Les formats de métasyntaxe décrits dans Section 9.7.3.4 n'existent pas dans XQuery.

  • Les lettres de drapeau pour expression rationnelle définis par XQuery sont liées, mais pas identiques aux lettres d'option pour POSIX (Tableau 9.23). Alors que les options i et q se comportent de la même façon, d'autres ne le font pas :

    • Les drapeaux s (permet au point de correspondre à un retour chariot) et m (permet à ^ et $ de correspondre à des retours chariot) avec XQuery donnent accès au même comportement que les drapeaux n, p et w avec POSIX, mais ils ne correspondent pas au comportement des drapeaux s et m avec POSIX. Notez en particulier que le point-correspond-retour-chariot est le comportement par défaut dans POSIX mais pas dans XQuery.

    • Le drapeau x (ignore un espace blanc dans le motif) de XQuery est très différent du drapeau de mode avancé dans POSIX. Le drapeau x de POSIX permet aussi à # de commencer un commentaire dans le motif et POSIX n'ignorera pas un caractère espace blanc après un antislash.