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

9.7. Correspondance de motif #

Il existe trois approches séparées concernant la correspondance de motif fournies par PostgreSQL : l'opérateur SQL LIKE habituel, l'opérateur SIMILAR TO plus récent (ajouté dans SQL:1999), et les expressions rationnelles style POSIX. En dehors des opérateurs basiques du type « est-ce que cette chaîne correspond à ce motif ? », des fonctions sont disponibles pour extraire ou remplacer des sous-chaînes et pour diviser une chaîne aux emplacements correspondant.

Astuce

Si vous avez des besoins sur la correspondance de motif qui vont au dela de ceci, pensez à écrire une fonction en Perl ou Tcl.

Attention

Bien que la plupart des recherches par expression rationnelles peut être exécutée très rapidement, des expressions rationnelles peuvent être conçues de telle façon qu'elles récupèrent des quantités arbitraires de temps et de mémoire pour le traitement. Faites attention si vous acceptez des expressions rationnelles à partir de sources hostiles. Si vous devez le faire, il est conseillé d'imposer une durée limite d'exécution pour la requête.

Les recherches utilisant des motifs SIMILAR TO ont les mêmes problèmes de sécurité car SIMILAR TO fournit un grand nombre de fonctionnalités identiques à celles des expressions rationnelles style POSIX.

Les recherches LIKE, étant plus simples que les deux autres options, sont plus sûres à utiliser avec des sources potentiellement hostiles.

Les opérateurs de correspondance de motifs des trois types ne supportent pas les collations non déterministes. Si nécessaire, appliquez une collation différente à l'expression pour contourner cette limitation.

9.7.1. LIKE #

string LIKE pattern [ESCAPE escape-character]
string NOT LIKE pattern [ESCAPE escape-character]
  

L'expression LIKE renvoie true si la chaîne string correspond au pattern fourni. (Comme attendu, l'expression NOT LIKE renvoie false si LIKE renvoie true, et vice versa. Une expression équivalente est NOT (string LIKE pattern).)

Si pattern ne contient pas de signe pourcent ou de tiret bas, alors le motif représente seulement la chaîne elle-même ; dans ce cas, LIKE agit comme l'opérateur d'égalité. Un tiret bas (_) dans pattern établit une correspondance avec n'importe quel caractère, mais un seul ; un signe pourcent (%) établit une correspondance avec une séquence 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
   

La correspondance de motif de LIKE couvre toujours la chaîne complète. Du coup, s'il est préféré de réaliser une correspondance sur une séquences n'importe où dans une chaîne, le motif doit commencer et finir avec un signe pourcent.

Pour faire une correspondance avec un tiret bas ou un signe pourcent, le caractère respectif dans pattern doit être précédé d'un caractère d'échappement. Le caractère d'échappement par défaut est l'antislash mais il est possible d'en sélectionner un autre en utilisant la clause ESCAPE. Pour faire une correspondance avec l'un de ces deux caractères, il faut écrire deux fois les caractères d'échappement.

Note

Si vous avez désactivé standard_conforming_strings, tout antislash écrit dans les constantes de chaîne aura besoin d'être doublé. Voir Section 4.1.2.1 pour plus d'informations.

Il est aussi possible de sélectionner un autre caractère d'échappement en écrivant ESCAPE ''. Ceci a pour conséquence de désactiver le mécanisme d'échappement, ce qui rend impossible de désactiver la signification spéciale des signes tiret bas et pourcent dans le motif.

D'après le standard SQL, omettre ESCAPE signifie qu'il n'y a pas de caractère d'échappement (plutôt que d'avoir antislash comme valeur par défaut), et une valeur ESCAPE de longueur zéro est interdite. Le comportement de PostgreSQL à ce niveau est donc contraire au standard.

Le mot clé ILIKE peut être utilisé à la place de LIKE pour rendre la correspondance insensible à la casse d'après la locale active. Ce mot clé n'est pas défini dans le standard SQL, il s'agit d'une extension de PostgreSQL.

L'opérateur ~~ est équivalent à LIKE, et ~~* correspond à ILIKE. Il existe aussi les opérateurs !~~ et !~~* qui représentent respectivement NOT LIKE et NOT ILIKE. Tous ces opérateurs sont spécifiques à PostgreSQL. Vous pourriez voir les noms de ces opérateurs dans le résultat de la commande EXPLAIN et dans des emplacements similaires, car l'analyseur traduit en fait LIKE et les autres en ces opérateurs.

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

De plus, voir l'opérateur commence-avec ^@ et la fonction correspondante starts_with, qui sont utiles dans les cas où une simple correspondance avec le début d'une chaîne est nécessaire.

9.7.2. Expressions rationnelles pour SIMILAR TO #

string SIMILAR TO pattern [ESCAPE escape-character]
string NOT SIMILAR TO pattern [ESCAPE escape-character]
  

L'opérateur SIMILAR TO renvoie true ou false suivant que le motif correspond ou non à la chaîne donnée. C'est similaire à LIKE, sauf qu'il interprète le motif en utilisant la définition du standard SQL d'une expression rationnelle. Les expressions rationnelles SQL sont un mixe étrange entre la notation LIKE et la notation d'expression rationnelle POSIX.

Tout comme LIKE, l'opérateur SIMILAR TO réussit seulement si son motif correspond à la chaîne entière ; c'est contraire au comportement commun des expressions rationnelles où le motif peut correspondre à toute partie de la chaîne. Encore une fois comme LIKE, SIMILAR TO utilise _ et % comme caractère joker dénotant respectivement tout caractère simple et toute (ils sont comparables à . et .* dans les expressions rationnelles POSIX).

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

  • | dénote le choix (entre deux alternatives).

  • * dénote la répétition de l'élément précédent zéro ou plusieurs fois.

  • + dénote la répétition de l'élément précédent une ou plusieurs fois.

  • ? dénote la répétition de l'élément précédent zéro ou une fois.

  • {m} dénote la répétition de l'élément précédent exactement m fois.

  • {m,} dénote la répétition de l'élément précédent m fois ou plus.

  • {m,n} dénote la répétition de l'élément précédent au moins m fois mais plus que que n fois.

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

  • Une expression entre crochets [...] indique une classe de caractères, tout comme dans les expressions rationnelles POSIX.

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

Comme avec LIKE, un antislash désactive la signification spéciale d'un de ces méta-caractères. Un caractère d'échappement différent peut être indiqué avec ESCAPE, et la possibilité d'échappement peut être désactivé avec ESCAPE ''.

D'après le standard SQL, omettre ESCAPE signifie qu'il n'y a pas de caractère d'échappement (plutôt que d'avoir comme valeur par défaut un antislash), et une valeur ESCAPE de longueur nulle est interdite. Le comportement de PostgreSQL dans ce cas est contraire au standard.

Une autre extension non standard est que faire suivre le caractère d'échappement d'une lettre ou d'un chiffre fournit un accès aux séquences d'échappement définies par les expressions rationnelles POSIX ; voir Tableau 9.20, Tableau 9.21 et Tableau 9.22 ci-dessous.

Quelques exemples :

'abc' SIMILAR TO 'abc'          true
'abc' SIMILAR TO 'a'            false
'abc' SIMILAR TO '%(b|d)%'      true
'abc' SIMILAR TO '(b|c)%'       false
'-abc-' SIMILAR TO '%\mabc\M%'  true
'xabcy' SIMILAR TO '%\mabc\M%'  false
   

La fonction substring avec trois paramètres fournit une extraction d'une sous-chaîne qui correspond à un motif d'expression rationnelle SQL. La fonction peut être écrite d'après la syntaxe du standard SQL :

substring(string similar pattern escape escape-character)

ou en utilisant la syntaxe maintenant obsolète SQL:1999 :

substring(string from pattern for escape-character)
   

ou comme une fonction simple avec trois arguments :

substring(string, pattern, escape-character)
   

Comme avec SIMILAR TO, le motif spécifié doit correspondre à la chaîne de données entière. Dans le cas contraire, 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 occurences du caractère d'échappement suivi par un guillemet double ("). Le texte correspondant à la portion du motif entre ces séparateurs est renvoyé quand la correspondance est réussie.

Les séparateurs échappement-guillemet-double divisent en fait le motif de substring en trois expressions rationnelles indépendantes ; par exemple, une barre verticale (|) dans une des trois sections affecte seulement uniquement cette section. De plus, la première et la troisième des expressions rationnelles sont définies pour correspondre à la plus petite quantité de texte, pas à la plus grande, quand il y a une ambiguité sur quelle quantité de données il y a correspondance avec le motif. (Dans la langue POSIX, on dit que la première et la troisième expressions rationnelles sont restreintes pour ne pas être gourmandes, non-greedy en anglais.)

En tant qu'extension au standard SQL, PostgreSQL permet qu'il y ait juste un caractère pour l'échappement des guillemets doubles, auquel cas la troisième expression rationnelle est comprise comme vide ; ou sans séparateur, auquel cas la première et la troisième expressions rationnelles sont comprises comme vides.

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

substring('foobar' similar '%#"o_b#"%' escape '#')   oob
substring('foobar' similar '#"o_b#"%' escape '#')    NULL
   

9.7.3. Expressions rationnelles POSIX #

Tableau 9.16 liste les opérateurs disponibles pour faire de la correspondance de motif en utilisant les expressions rationnelles.

Tableau 9.16. Opérateurs de correspondance d'expressions rationnelles

Opérateur

Description

Exemple(s)

text ~ textboolean

La chaîne correspond à l'expression rationnelle, casse comprise

'thomas' ~ 't.*ma't

text ~* textboolean

La chaîne correspond à l'expression rationnelle, sans prise en compte de la casse

'thomas' ~* 'T.*ma't

text !~ textboolean

La chaîne ne correspond pas à l'expression rationnelle, casse comprise

'thomas' !~ 't.*max't

text !~* textboolean

La chaîne ne correspond pas à l'expression rationnelle, sans prise en compte de la casse

'thomas' !~* 'T.*ma'f


Les expressions rationnelles POSIX fournit un moyen bien plus puissant pour la correspondance de motif que les opérateurs LIKE et SIMILAR TO. Un grand nombre d'outils Unix comme egrep, sed ou awk utilise un langage de correspondance de motif similaire à celui décrit ici.

Une expression rationnelle est une séquence de caractères qui est une définition courte d'un ensemble de chaînes (un ensemble rationnel). Une chaîne est dite correspondre à une expression rationnelle si elle est un membre de l'ensemble rationnel décrit par l'expression rationnelle. Tout comme avec LIKE, les caractères du motif correspondent exactement aux caractères de la chaîne sauf dans le cas de caractères spéciaux du langage d'expression rationnelle -- mais les expressions rationnelles utilisent différents caractères spéciaux comme le fait LIKE. Contrairement aux motifs LIKE, une expression rationnelle est autorisée à établir une correspondance n'importe où dans une chaîne, sauf si l'expression rationnelle est explicitement ancrée au début ou à la fin de la chaîne.

Quelques exemples :

+'abcd' ~ 'bc'     true
+'abcd' ~ 'a.c'    true  --  le point correspond à tout caractère
+'abcd' ~ 'a.*d'   true  --  * répète l'élément de motif précédent
+'abcd' ~ '(b|x)'  true  --  | signifie OU, pour le groupe entre parenthèses
+'abcd' ~ '^a'     true  --  ^ attache au début de la chaîne
+'abcd' ~ '^(b|c)' false  --  correspondrait sauf pour l'attache
   

Le langage de motif POSIX est décrit avec bien plus de détails ci-dessous.

La fonction substring avec deux arguments, substring(string from pattern), propose l'extraction d'une sous-chaîne correspondant à un motif d'expression rationnelle POSIX. Elle renvoie NULL s'il n'y a aucune correspondance, et renvoie la première portion du texte correspondant au motif. Mais si le motif contient des parenthèses, la portion du texte correspondant à la première sous-expression entre parenthèses (celle où la parenthèse gauche arrive en premier) est renvoyée. Vous pouvez placer les parenthèses autour de l'expression entière si vous voulez utiliser des parenthèses dans le motif sans déclencher cette exception. Si vous avez besoin des parenthèses dans le motif avant la sous-expression que vous voulez extraire, voir les parenthèses sans capture décrites ci-dessous.

Quelques exemples :

substring('foobar' from 'o.b')     oob
substring('foobar' from 'o(.)b')   o
   

La fonction regexp_count compte le nombre de places où un motif d'expression rationnelle POSIX correspond à une chaîne. Elle a la syntaxe regexp_count(string, pattern [, start [, flags ]]). pattern est recherché dans string, normalement à partir du début de la chaîne mais si le paramètre start est fourni, alors la recherche commence à partir de cette position. Le paramètre flags est une chaîne de texte optionnelle contenant zéro ou plus d'options sous la forme de lettres individuelles, modifiant le comportement de la fonction. Par exemple, inclure i dans flags force une correspondance sans sensibilité à la casse. Les options acceptées sont décrites dans Tableau 9.24.

Voici quelques exemples :

regexp_count('ABCABCAXYaxy', 'A.')          3
regexp_count('ABCABCAXYaxy', 'A.', 1, 'i')  4

La fonction regexp_instr renvoie la position de départ ou de fin de la N-ième correspondance d'un motif d'expression rationnelle POSIX dans une chaîne, ou zéro s'il n'y a pas de correspondance. La syntaxe est la suivante : regexp_instr(string, pattern [, start [, N [, endoption [, flags [, subexpr ]]]]]). pattern est recherché dans string, normalement à partir du début de la chaîne, mais si le paramètre start est fourni, alors la recherche commence à partir de cette position. Si N est spécifié, alors la N-ième correspondance du motif est recherché, sinon ce sera la première. Si le paramètre endoption est omis ou vaut zéro, la fonction renvoie la position du premier caractère de la correspondance. Sinon, endoption doit valoir un, et la fonction renvoie la position du caractère suivant la correspondance. Le paramètre flags est une chaîne de texte optionnelle contenant zéro ou plus options, sous la forme de lettres individuelles, changeant le comportement de la fonction. Les options acceptées sont décrites dans Tableau 9.24. Pour un motif contenant des sous-expressions entre parenthèses, subexpr est un entier indiquant la sous-expression d'intérêt : le résultat identifie la position de la sous-chaîne correspondant à cette sous-expression. Les sous-expressions sont numérotées dans l'ordre de leur première parenthèse. Quand subexpr est omis ou vaut zéro, le résultat identifie la position de la correspondance totale plutôt que celle des sous-expressions entre parenthèses.

Voici quelques exemples :

regexp_instr('number of your street, town zip, FR', '[^,]+', 1, 2)
                                   23
regexp_instr('ABCDEFGHI', '(c..)(...)', 1, 1, 0, 'i', 2)
                                   6

La fonction regexp_like vérifie si une correspondance d'un motif d'expression rationnelle POSIX survient dans une chaîne, renvoyant un booléen true ou false. Voici sa syntaxe : regexp_like(string, pattern regexp_replace(source, pattern, replacement [, flags ]). Le paramètre flags est une chaîne de texte optionnelle contenant zéro ou plus options, indiquées par des lettres individuelles qui modifient le comportement de la fonction. Les options acceptées sont décrites dans Tableau 9.24. Cette fonction a les mêmes résultats que l'opérateur ~ si aucune option n'est indiquée. Si seule l'option i est indiquée, elle a les mêmes résultats que l'opérateur ~*.

Quelques exemples :

regexp_like('Hello World', 'world')       false
regexp_like('Hello World', 'world', 'i')  true
   

La fonction regexp_match renvoie un tableau texte des sous-chaînes capturées résultant de la première correspondance au motif d'une expression rationnelle POSIX avec une chaîne. Elle a la syntaxe regexp_match(string, pattern [, flags ]). S'il n'y a aucune correspondance, le résultat est NULL. Si une correspondance est trouvée et que pattern ne contient aucune sous-expression entre parenthèses, alors le résultat est un tableau texte à un seul élément contenant la sous-chaîne correspondance au motif entier. Si une correspondance est trouvée et que pattern contient des sous-expressions entre parenthèses, alors le résultat est un tableau texte où le n-ième élément est la sous-chaîne correspondant à la n-ième sous-expression entre parenthèses de pattern (sans compter les parenthèses « sans capture » ; voir ci-dessous pour les détails). Le paramètre flags est une chaîne de texte optionnel contenant zéro ou plusieurs drapeaux de lettres individuelles qui changent le comportement de la fonction. Les drapeaux acceptés sont décrit dans Tableau 9.24.

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)
   

Astuce

Dans le cas commun où vous voulez seulement la sous-chaîne complète correspondante ou NULL s'il n'y a pas de correspondance, la meilleure solution revient à utiliser regexp_substr(). Néanmoins, regexp_substr() existe seulement dans PostgreSQL version 15 et les versions ultérieures. Si vous utilisez une version plus ancienne, vous pouvez extraire le premier élément du résultat de regexp_match(), par exemple :

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

La fonction regexp_matches renvoie un ensemble de tableaux de texte des sous-chaînes correspondantes résultant d'une correspondance d'un motif d'expression rationnelle POSIX à une chaîne. Elle a la même syntaxe que regexp_match. Cette fonction ne renvoie aucune ligne s'il n'y a pas de correspondance, une ligne s'il y a une correspondance et que le drapeau g n'a pas été utilisé, ou N lignes s'il y a N correspondances et que le drapeau g a été utilisé. Chaque ligne renvoyée est un tableau texte contenant la sous-chaîne entière correspondante ou les sous-chaînes correspondant aux sous-expressions entre parenthèses de pattern, comme décrit ci-dessus pour regexp_match. regexp_matches accepte tous les drapeaux discutés dans Tableau 9.24, plus le drapeau g qui requiert le renvoi de toutes les correspondances, et non pas seulement de 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é avec le drapeau g car, si vous voulez seulement la première correspondance, il est plus simple et plus efficace d'utiliser regexp_match(). Néanmoins, regexp_match() existe seulement à partir de la version 10 de PostgreSQL. Sur les anciennes versions, une astuce connue est de placer un appel à regexp_matches() dans une sous-requête, par exemple :

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

Ceci produit un tableau de texte s'il y a une correspondance ou NULL dans le cas contraire, comme le ferait regexp_match(). Sans la sous-requête, cette requête ne produirait aucun résultat pour les lignes de la table sans correspondance, ce qui n'est pas le comportement désiré habituellement.

La fonction regexp_replace fournit la substitution par un nouveau texte pour les sous-chaînes qui correspondent aux motifs d'expression rationnelle POSIX. Elle a cette syntaxe : regexp_replace(source, pattern, replacement [, start [, N ]] [, flags ]). (Notez que that N ne peut être indiqué que si start l'est, mais flags peut être donné dans tous les cas.) La chaîne source est renvoyée non modifiée s'il n'y a pas de correspondance avec pattern. S'il existe une correspondance, la chaîne source est renvoyée avec la chaîne replacement substituant la sous-chaîne qui a établi la correspondance. La chaîne replacement peut contenir \n, où n vaut de 1 à 9, pour indiquer que la sous-chaîne source correspondant à la n-ième sous-expression entre parenthèses du motif doit être insérée. Il peut aussi contenir \& pour indiquer que la sous-chaîne correspondant au motif entier doit être insérée. Écrire \\ si vous avez besoin d'un antislash litéral dans le texte de remplacement. pattern est recherché dans string, normalement à partir du début de la chaîne mais si le paramètre start est fourni, alors la recherche commence à cette position de la chaîne. Par défaut, seule la première occurrence du motif est remplacée. Si N est indiqué et est plus grand que zéro, alors la N-ième correspondance du motif est remplacée. Si l'option g est utilisé ou si N est indiqué et vaut zéro, alors toutes les correspondances sur ou après la position start sont remplacées. (L'option g est ignorée quand N est spécifiée.) Le paramètre flags est une chaîne de texte optionnelle contenu zéro ou plus options, indiquées par des lettres individuelles, modifiant le comportement de la fonction. Les options acceptées (sauf g) sont décrites dans Tableau 9.24.

Voici quelques exemples :

regexp_replace('foobarbaz', 'b..', 'X')
                                   fooXbaz
regexp_replace('foobarbaz', 'b..', 'X', 'g')
                                   fooXX
regexp_replace('foobarbaz', 'b(..)', 'X\1Y', 'g')
                                   fooXarYXazY
regexp_replace('A PostgreSQL function', 'a|e|i|o|u', 'X', 1, 0, 'i')
                                   X PXstgrXSQL fXnctXXn
regexp_replace('A PostgreSQL function', 'a|e|i|o|u', 'X', 1, 3, 'i')
                                   A PostgrXSQL function

La fonction regexp_split_to_table divise une chaîne utilisant un motif d'expression rationnelle POSIX comme délimiteur. Elle a la syntaxe regexp_split_to_table(string, pattern [, flags ]). S'il n'y a aucune correspondance avec pattern, la fonction renvoie string. 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 du début de la chaîne) jusqu'au début de la correspondance. Quand il n'y a plus de correspondance, elle renvoie le texte de la fin de la dernière correspondance à la fin de la chaîne. Le paramètre flags est une chaîne de texte optionnelle contenant zéro ou plusieurs drapeaux de lettres individuelles qui modifient le comportement de la fonction. regexp_split_to_table accepte les drapeaux décrits dans Tableau 9.24.

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 comme un tableau de text. Elle a la syntaxe regexp_split_to_array(string, pattern [, flags ]). 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 démontre le dernier exemple, les fonctions de division d'expressions rationnelles ignorent les correspondances de longueur zéro survenant au début et à la fin de la chaîne ou immédiatement après la correspondance précédente. Ceci est contraire à la définition stricte de la correspondance d'expression rationnelle telle qu'elle est implémentée par les autres fonctions regexp, mais c'est généralement le comportement le plus intéressant en pratique. Les autres logiciels tels que Perl utilisent des définitions similaires.

La fonction regexp_substr renvoit la sous-chaîne correspondant à un motif d'expression rationnelle POSIX, ou NULL s'il n'y a pas de correspondances. Voici sa syntaxe : regexp_substr(string, pattern [, start [, N [, flags [, subexpr ]]]]). pattern est recherché dans string, normalement à partir du début de la chaîne mais si le paramètre start est fourni, alors la recherche commence à partir de cette position. Si N est indiqué, alors la N-ième correspondance du motif est renvoyé, sinon ce sera la première correspondance. Le paramètre flags est une chaîne de texte optionnelle contenant zéro ou plusieurs options, indiquées chacune par une lettre indivuelle, changeant le comportement de la fonction. Les options acceptées sont décrites dans Tableau 9.24. Pour un motif contenant des sous-expressions entre parenthèses, subexpr est un entier désignant la sous-expression d'intérêt : le résultat est la sous-chaîne correspondant à cette sous-expression. Les sous-expressions sont numérotées dans l'ordre de leur première parenthèse. Quand subexpr est omis ou vaut zéro, le résultat est la correspondance complète quelque soit les sous-expressions entre parenthèses.

Voici quelques exemples :

regexp_substr('number of your street, town zip, FR', '[^,]+', 1, 2)
                                    town zip
regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2)
                                   FGH

9.7.3.1. Détails sur les expressions rationnelles #

Les expressions rationnelles de PostgreSQL sont implémentées en utilisant un paquet logiciel écrit par Henry Spencer. La plupart des descriptions d'expressions rationnelles ci-dessous est copiée verbatim de son manuel.

Les expressions rationnelles (connus sous l'acronyme RE), tel qu'elles sont définies dans POSIX 1003.2, viennent sous deux formes : les RE étendues ou ERE (en gros celles de egrep), et les RE basiques ou BRE (en gros celles de ed). PostgreSQL accepte les deux formes, et implémente aussi certaines extensions qui ne font pas partie du standard POSIC, mais sont devenues largement utilisées grâce à leur disponibilité dans les langages de programmation tels que Perl et Tcl. Les RE utilisant ces extensions de POSIX sont appelées des RE avancées ou ARE dans cette documentation. Les ARE sont pratiquement un sur-ensemble des ERE, mais les BRE ont des incompatibilités de notation (et sont bien plus limitées). Nous décrivons tout d'abord les formes ARE et ERE, en notant les fonctionnalités qui s'appliquent uniquement aux ARE, puis nous décrivons comment les BRE diffèrent.

Note

PostgreSQL présume toujours au départ qu'une expression rationnelle suit les règles ARE. Néanmoins, les règles ERE plus limitées ou les règles BRE peuvent être choisies en ajoutant une option intégrée au motif RE, comme décrit dans Section 9.7.3.4. Ceci peut être utile pour la compatibilité avec les applications qui s'attendent à un respect strict des règles POSIX 1003.2.

Une expression rationnelle est définie comme une ou plusieurs branches, séparées par |. Elle correspond à tout ce qui correspond à une des branches.

Une branche est zéro ou plus atomes quantifiés ou contraintes, concaténés. Elle établie une correspondance pour le premier, puis pour le second, etc ; une branche vide établit une correspondance à une chaîne vide.

Un atome quantifié est un atome potentiellement suivi par un quantifieur simple. Sans quantifieur, il peut établir une correspondance pour l'atome. Avec un quantifieur, il peut établir un certain nombre de correspondances à l'atome Un atom peut être une des possibilités indiquées dans Tableau 9.17. Les quantifieurs possibles et leur signification sont montrés dans Tableau 9.18.

Une contrainte correspond à une chaîne vide, mais correspond seulement quand certaines conditions spécifiques sont rencontrées. Une contrainte peut être utilisée là où un atome peut être utilisé, sauf qu'il ne peut pas être suivi d'un quantifieur. Les contraintes simples sont montrées dans Tableau 9.19 ; d'autres contraintes sont décrites après.

Tableau 9.17. Atomes d'expression rationnelle

AtomeDescription
(re) (où re est toute expression rationnelle) établit une correspondance pour re, avec une correspondance notée pour une capture possible
(?:re) comme ci-dessus, mais la correspondance n'est pas notée pour une capture (un ensemble de parenthèses « sans capture ») (ARE seulement)
. correspond à tout caractère individuel
[chars] une expression entre crochets, correspondant à un des caractères parmi chars (voir Section 9.7.3.2 pour plus de détails)
\k (où k est un caractère non alpha-numérique) correspond à ce caractère pris comme un caractère ordinaire, par exemple \\ correspond à un caractère antislash
\c c est un caractère alpha-numérique (potentiellement suivi par d'autres caractères) est un échappement, voir Section 9.7.3.3 (ARE seulement ; pour les ERE et BRE, ceci correspond à c)
{ quand suivi par un caractère autre qu'un chiffre, correspond au caractère { ; quand suivi d'un chiffre, c'est le début d'une limite (voir ci-dessous)
x x est un simple caractère sans signification particulière, correspond à ce caractère

Un RE ne peut pas se terminer avec un antislash (\).

Note

Si vous avez désactivé standard_conforming_strings, tout antislash que vous écrivez dans des constantes de chaînes de caractères devra être doublé. Voir Section 4.1.2.1 pour plus d'informations.

Tableau 9.18. Quantifieur pour expression rationnelle

QuantifieurCorrespondance
* une séquence de 0 ou plus correspondances de l'atome
+ une séquence de 1 ou plus correspondances de l'atome
? une séquence de 0 ou 1 correspondances de l'atome
{m} une séquence de 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 correspondances (nombre inclus) de l'atome ; m ne peut pas dépasser 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 utilisant {...} sont connues comme des limites. Les nombres m et n d'une limite sont des entiers décimaux non signés avec des valeurs autorisées allant de 0 à 255, valeurs comprises.

Des quantifieurs non gourmands (Non-greedy en VO), disponibles uniquement dans les ARE, correspondent aux mêmes capacités que leur version gourmande correspondante (greedy), mais préfèrent le plus petit nombre plutôt que le plus grand nombre de correspondantes. Voir Section 9.7.3.5 pour plus de détails.

Note

Un quantifieur ne peut pas suivre immédiatement un autre quantifieur, par exemple ** est invalide. Un quantifieur ne peut pas commencer une expression ou une sous-expression, ou suivre ^ ou |.

Tableau 9.19. Contraintes d'expression rationnelle

ContrainteDescription
^ correspond au début de la chaîne
$ correspond à la fin de la chaîne
(?=re) recherche en avance positive correspond à tout point où une sous-chaîne correspondant à re commence (ARE seulement)
(?!re) recherche en avance négative correspond à tout point où aucune sous-chaîne correspondant à re commence (ARE seulement)
(?<=re) recherche en arrière positive correspond à tout point où une sous-chaîne correspondant à re termine (ARE seulement)
(?<!re) recherche en arrière négative correspond à tout point où aucune sous-chaîne correspondant à re termine (ARE seulement)

Les contraintes de recherche en avant et de recherche en arrière ne peuvent pas contenir des références arrières (voir Section 9.7.3.3), et toutes les parenthèses comprises en elles sont considérées comme non capturantes.

9.7.3.2. Expressions entre crochets #

Une expression entre crochets est une liste de caractères compris dans []. Cela établit habituellement une correspondance avec tout caractère seul à partir de la liste (mais voir ci-dessous). Si la liste commence avec ^, cela établit une correspondance avec tout caractère seul ne faisant pas parti de la liste. Si deux caractères de la liste sont séparés par un caractère -, c'est un raccourci pour l'intervalle complet de caractères entre ces deux caractères (en les incluant) dans la séquence, par exemple [0-9] en ASCII correspond à tout chiffre décimal. Il est illégal pour deux intervalles de partager la même limite finale, par exemple a-c-e. Les intervalles sont particulièrement dépendants de la collation, donc les programmes portables devraient éviter de se baser sur eux.

Pour inclure un caractère ] littéral dans la liste, faites-en le premier caractère (après ^, si nécessaire). Pour inclure un - littéral, faites-en le premier ou dernier caractère, ou le deuxième point final d'un intervalle. Pour utiliser un - littéral comme premier point final d'un intervalle, placez le entre [. et .] pour en faire un élément d'assemblage (voir ci-dessous). À l'exception de ces caractères, certaines combinaisons utilisant [ (voir les prochains paragraphes), et des échappements (ARE seulement), tous les autres caractères spéciaux perdent leur signification à l'intérieur d'une expression entre crochets. En particulier, \ n'est pas spécial quand il suit les règles ERE et BRE, bien qu'il soit spécial (pour introduire un échappement) dans les ARE.

À l'intérieur d'une expression entre crochets, un élément d'assemblage (un caractère, une séquence multi-caractères qui s'assemblent comme s'il s'agissait d'un seul caractère, ou un nom de séquence d'assemblage) englobé dans [. and .] signifie la séquence de caractères de cet élément d'assemblage. La séquence est traitée comme un seul élément de liste d'expression entre crochets. Ceci permet à une expression entre crochets contenant un élément d'assemblage multi-caractères de correspondre à plus d'un caractère. Par exemple, si la séquence d'assemblage inclut un élément d'assemblage ch, alors le RE [[.ch.]]*c correspond aux cinq premiers caractères de chchcc.

Note

PostgreSQL n'accepte pas actuellement les éléments d'assemblage multi-caractères. Cette information décrit un comportement futur possible.

À l'intérieur d'une expression entre crochets, un élément d'assemblage compris entre [= et =] est une classe d'équivalence, représentant les séquences de caractères de tous les éléments d'assemblage équivalent à cette classe, incluant lui-même. (S'il n'existe pas d'autres éléments d'assemblage équivalents, le traitement est identique, comme si les délimiteurs étaient [. et .].) Par exemple, si o et ^ sont les membres d'une classe d'équivalence, alors [[=o=]], [[=^=]] et [o^] sont tous synonymes. Une classe d'équivalent ne peut pas être un point final d'un intervalle.

À l'intérieur d'une expression entre crochets, le nom d'une classe de caractères entouré entre [: et :] signifie la liste de tous les caractères appartenant à cette classe. Une classe de caractères ne peut pas être utilisée comme point final d'un intervalle. Le standard POSIX définit les noms de ces classes de caractères : alnum (lettres et chiffres), alpha (lettres), blank (espace et tabulation), cntrl (caractères de contrôle), digit (chiffres), graph (caractères affichages, sauf l'espace), lower (lettres minuscules), print (caractères affichages, incluant l'espace), punct (ponctuation), space (tout espace blanc), upper (lettres majuscules), et xdigit (chiffres hexadécimaux). Le comportement de ces classes de caractères standards est généralement cohérent sur les plateformes pour les caractères de l'ensemble ASCII 7 bits. Qu'un caractère non ASCII donné appartienne ou non à une de ces classes dépend de la collation utilisée par la fonction ou l'opérateur de l'expression rationnelle, (voir Section 24.2), ou par défaut de la locale indiquée par LC_CTYPE pour cette base (voir Section 24.1). La classification de caractères non ASCII peut varier entre les plateformes même pour des locales de nom similaire. (Mais la locale C ne considère jamais tout caractère non ASCII comme appartenant à une de ces classes.) En plus de ces classes de caractères standard, PostgreSQL définit la classe de caractères mot, ce qui revient au même que alnum plus le caractère underscore (_), et la classe de caractères ascii, qui contient l'ensemble ASCII 7 bits exactement.

Il existe deux cas spéciaux d'expressions entre crochets : les expressions entre crochets [[:<:]] et [[:>:]] sont des contraintes, correspondant à des chaînes vides au début et à la fin d'un mot caractère respectivement. Un mot est défini comme une séquence de mots qui n'est ni précédée ni suivie de mots. Un mot caractère correspond à n'importe quel caractère appartenant à la classe de caractères word, c'est-à-dire n'importe quel lettre, nombre ou l'underscore. C'est une extension, compatible avec, mais non spécifiée par POSIX 1003.2, et elle devrait être utilisée avec précaution dans les logiciels portables sur d'autres systèmes. Les échappements de contrainte décrits ci-dessous sont généralement préférables ; ils ne sont pas plus standards, mais plus simples à écrire.

9.7.3.3. Échappements d'expression rationnelle #

Les échappements sont des séquences spéciales commençant avec \ et suivies par un caractère alphanumérique. Les échappements sont de différents types : entrée de caractère, raccourci de classe, échappements de contrainte, et références. Un \ suivi d'un caractère alphanumérique mais ne constituant pas un échappement valide est illégal dans les ARE. Dans le ERE, il n'y a pas d'échappement : en dehors d'une expression entre crochets, un \ suivi d'un caractère alpha-numérique signifie ce caractère alors qu'à l'intérieur d'une expression entre crochets, \ est un caractère standard. (Ce dernier est la seule incompatibilité entre ERE et ARE.)

Les échappements d'entrée de caractère existent pour rendre plus simple l'ajout de caractères non affichables, ainsi que d'autres caractères désagréables à saisir dans les RE. Ils sont affichés dans Tableau 9.20.

Les échappements de raccourci de classe fournissent des raccourcis pour certaines classes de caractères fréquemment utilisées. Ils sont affichés dans Tableau 9.21.

Un échappement de contrainte est une contrainte, correspondant à la chaîne vide si des conditions spécifiques sont rencontrées, écrites comme un échappement. Ils sont affichés dans Tableau 9.22.

Une référence (\n) établit une correspondance de la même chaîne avec la sous-expression entre parenthèses précédente spécifiée par le numéro n (voir Tableau 9.23). Par exemple, ([bc])\1 établit une correspondance avec bb et cc, mais pas bc et cb. La sous-expression doit précéder entièrement la référence dans le RE. Les sous-expressions sont numérotées dans l'ordre de leur parenthèses de début. Les parenthèses sans capture ne définissent pas de sous-expressions. La référence considère seulement la chaîne de caractères correspondant à la sous-expression référencée, pas les contraintes qu'elle contient. Par exemple, (^\d)\1 établira une correspondance avec 22.

Tableau 9.20. Échappements d'entrée de caractère pour les expressions rationnelles

ÉchappementDescription
\a caractère alerte (cloche), comme en C
\b suppression, comme en C
\B synonyme pour antislash (\) pour aider à réduire le doublement d'antislash
\cX (où X est tout caractère) le caractère dont les 5 bits de poids faible sont les mêmes que X, et dont tous les autres bits valent zéro
\e le caractère donc le nom de séquence d'assemblage est ESC, ou, en dehors de cela, le caractère de valeur octale 033
\f form feed, comme en C
\n nouvelle ligne, comme en C
\r retour chariot, comme en C
\t tabulation horizontale, comme en C
\uwxyz (où wxyz est exactement quatre chiffres hexadécimaux) le caractère dont la valeur hexadécimale est 0xwxyz
\Ustuvwxyz (où stuvwxyz est exactement huit chiffres hexadécimaux) le caractère dont la valeur hexadécimale est 0xstuvwxyz
\v tabulation verticale, comme en C
\xhhh (où hhh est toute séquence de chiffres hexadécimaux) le caractère dont la valeur hexadécimale est 0xhhh (un seul caractère, peu importe le nombre de chiffres hexadécimaux utilisés)
\0 le caractère dont la valeur est 0 (l'octet nul)
\xy (où xy est exactement deux chiffres octals, et n'est pas une référence) le caractère dont la valeur octale est 0xy
\xyz (où xyz est exactement trois chiffres octales, et n'est pas une 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 d'entrés de caractères numériques spécifiant des valeurs en dehors de l'intervalle ASCII (0–127) ont des significations dépendantes de l'encodage de la base de données. Quand l'encodage est UTF-8, les valeurs d'échappement sont équivalents à des points code Unicode. Par exemple, \u1234 signifie le caractère U+1234. Pour les autres encodages multi-octets, les échappements d'entrée de caractères spécifient habituellement juste la concaténation des valeurs d'octet pour le caractère. Si la valeur d'échappement ne correspond pas à tout caractère légale dans l'encodage de la base de données, aucune erreur ne sera levée, mais elle ne correspondra à aucune donnée.

Les échappements d'entrée de classe 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.21. Échappements de raccourci de classe pour les expressions rationnelles

ÉchappementDescription
\d correspond à n'importe quel chiffre, comme [[:digit:]]
\s correspond à tout espace blanc, comme [[:space:]]
\w correspond à n'importe quel mot, comme [[:word:]_]
\D correspond à n'importe quel caractère non-chiffre, comme [^[:digit:]]
\S correspond à n'importe quel caractère non-espace blanc, comme [^[:space:]]
\W correspond à n'import quel caractère non-mot, comme [^[:alnum:]_]

Les échappements de raccourci de classe fonctionnent également dans des expressions entre crochets, bien que les définitions ci-dessus ne soient pas tout-à-fait syntaxiquement valides dans ce contexte. Par exemple, [a-c\d] est équivalent à [a-c[:digit:]].

Tableau 9.22. Échappements de contraintes pour les expressions rationnelles

ÉchappementDescription
\A correspond seulement au début de la chaîne (voir Section 9.7.3.5 sur comment cela diffère de ^)
\m correspond seulement au début d'un mot
\M correspond seulement à la fin d'un mot
\y correspond seulement au début ou à la fin d'un mot
\Y correspond seulement à un point qui n'est pas le début ou la fin d'un mot
\Z correspond seulement à la fin de la chaîne (voir Section 9.7.3.5 sur comment cela diffère de $)

Un mot est défini comme dans la spécification de [[:<:]] et [[:>:]] ci-dessus. Les échappements de contrainte sont illégales à l'intérieur d'une expression entre crochets.

Tableau 9.23. Références d'expressions rationnelles

ÉchappementDescription
\m (où m est un chiffre différent de zéro) une référence à la m-ième sous-expression
\mnn (où m est un chiffre différent de zéro, et nn est quelques chiffres, et la valeur décimale de mnn n'est pas supérieure au nombre de parenthèses fermantes capturantes vues jusqu'à maintenant) une référence à la mnn-ième sous-expression

Note

Il existe une ambiguité inhérente entre les échappements d'entrée de caractères en octal et les références. Cette ambiguité est résolue avec les heuristiques suivantes, comme indiqué ci-dessus. Un zéro en début indique toujours un échappement octal. Un chiffre seul différent de zéro, qui n'est pas suivi par un autre chiffre est toujours pris pour une référence. Une séquence de plusieurs chiffres ne commençant pas par un zéro est pris pour une référence si elle survient après une sous-expression acceptable (c'est-à-dire que le numéro est dans l'intervalle légal pour une référence), et sinon est pris pour un octal.

9.7.3.4. Méta-syntaxe des expressions rationnelles #

En plus de la syntaxe principale décrite ci-dessus, il existe des formes spéciales et des fonctionnalités syntaxiques diverses disponibles.

Une RE peut commencer avec un des deux préfixes director spéciaux. Si une RE commence avec ***:, le reste de la RE est prise pour une ARE. (Ceci n'a normalement aucun effet dans PostgreSQL, car les RE sont supposées être des ARE ; mais cela a un effet si le mode ERE ou le mode BRE a été spécifié avec le paramètre flags dans une fonction d'expression rationnelle.) Si une RE commence avec ***=, le reste de la RE est prise comme une chaîne littérale, tous les caractères étant considérés comme des caractères ordinaires.

Une ARE peut commander avec des options intégrées : une séquence (?xyz) (où xyz est un ou plusieurs caractères alphabétiques) indique des options affectant le reste de la RE. Ces options surchargent toutes les options préalablement déterminées -- en particulier, elles peuvent surcharger le comportement de sensibilité à la base impliqué par un opérateur d'expression rationnelle ou le paramètre flags d'une fonction d'expression rationnelle. Les lettres disponibles pour les options sont indiquées dans Tableau 9.24. Notez que ces mêmes lettres sont utilisées dans les paramètres flags des fonctions d'expression rationnelle.

Tableau 9.24. Lettres pour options intégrées des ARE

OptionDescription
b le reste de la RE est une BRE
c correspondance sensible à la casse (surcharge le type d'opérateur)
e le reste de la RE est une ERE
i correspondance insensible à la casse (voir Section 9.7.3.5) (surcharge le type d'opérateur)
m synonyme historique pour n
n correspondance sensible à la nouvelle ligne (voir Section 9.7.3.5)
p correspondance partielle sensible à la nouvelle ligne (voir Section 9.7.3.5)
q le reste de la RE est une chaîne littérale (« entre guillemets »), avec tous les caractères ordinaires
s correspondance non sensible à la nouvelle ligne (par défaut)
t syntaxe serrée (par défaut ; voir ci-dessous)
w correspondance partielle inverse à la nouvelle ligne (voir Section 9.7.3.5)
x syntaxe étendue (voir ci-dessous)

Les options intégrées prennent effet au ) terminant la séquence. Elles peuvent apparaître seulement au début d'une ARE (après le directeur ***: le cas échéant).

En plus de l'habituelle syntaxe RE (serrée), dans laquelle tous les caractères sont signifiants, il existe une syntaxe étendue, disponible en spécifiant l'option étendue x. Dans la syntaxe étendue, les caractères d'espace blanc de la RE sont ignorés, comme le sont tous les caractères entre un # et la nouvelle ligne suivante (ou la fin de la RE). Ceci permet les paragraphes et les commentaires dans une RE complexe. Il existe trois exceptions à cette règle basique :

  • un caractère espace blanc ou un # précédé par \ est retenu

  • un espace blanc ou un # dans une expression entre crochets est retenu

  • un espace blanc et les commentaires ne peuvent pas apparaître avec les symboles multi caractères, tels que (?:

Pour cela, les caractères d'espace blanc sont un blanc, une tabulation, un retour à la ligne et tout caractère qui appartient à la classe de caractères space.

Enfin, dans une ARE, les expressions en dehors des crochets, la séquence (?#ttt) (où ttt est tout texte ne contenant pas )) est un commentaire, complètement ignoré. Encore une fois, ceci n'est pas autorisé entre les caractères des symboles multi-caractères, comme (?:. De tels commentaires sont plus un artéfact historique qu'une fonctionnalité utile, et leur utilisation est déconseillée ; utilisez la syntaxe étendue à la place.

Aucune de ces extensions de métasyntaxe n'est disponible si un directeur ***= initial n'a spécifié que l'entrée de l'utilisateur doit être traitée comme une chaîne littérale plutôt que comme une RE.

9.7.3.5. Règles de correspondance des expressions rationnelles #

Dans le cas où une RE correspond à plus d'une sous-chaîne d'une chaîne donnée, la RE établit une correspondance avec la sous-chaîne la plus proche du début de la chaîne. Si la RE correspond à plus d'une sous-chaîne commençant à ce point, la correspondance conservée sera soit la plus longue, soir, la plus courte, suivant que la RE est gourmande (greedy) ou non (non-greedy).

Le fait qu'une RE est gourmande ou non se détermine avec les règles suivantes :

  • La plupart des atomes, et toutes les contraintes, n'ont pas d'attribut de gourmandise (parce qu'ils ne peuvent pas correspondre à des quantités variables de texte).

  • Ajouter des parenthèses autour d'une RE ne modifie pas sa gourmandise.

  • Un atome quantifié avec un quantifieur de répétition fixe ({m} ou {m}?) a la même gourmandise (potentiellement aucune) que l'atome lui-même.

  • Un atome quantifié avec d'autres quantifieurs standards (incluant {m,n} avec m égal à n) est gourmand (il préfère la correspondance la plus longue).

  • Un atome quantifié avec un quantifieur non gourmand (incluant {m,n}? avec m égal à n) est non gourmand (il préfère la correspondance la plus courte).

  • Une branche -- autrement dit, une RE qui n'a pas d'opérateur | hhaut niveau -- a la même gourmandise que le premier atome quantifié qui a un attribut de gourmandise.

  • Une RE consistant en deux ou plusieurs branches connectés par l'opérateur | est toujours gourmand.

Les règles ci-dessus associent les attributs de gourmandise non seulement aux atomes quantifiés individuels mais aussi aux branches et aux RE complets qui contiennent des atomes quantifiés. Cela signifie que la correspondance est faite de tel façon que la branche ou la RE complète correspondant à la sous-chaîne la plus longue ou la plus courte au complet. Une fois que la longueur de la correspondance entière est déterminée, la partie de celle-ci correspondant à une sous-expression particulière est déterminée sur la base de l'attribut de gourmandise de cette sous-expression, avec les sous-expressions commençant plus tôt dans la RE prenant priorité sur les autres.

Un exemple de ce que cela signifie :

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, la RE complète est gourmande parce que Y* est gourmand. Elle peut correspondance en commençant au Y, et elle correspond à la chaîne la plus longue commençant là, donc Y123. La sortie est la partie entre parenthèse, ou 123. Dans le deuxième cas, la RE complète est non gourmande parce que Y*? est non gourmande. Elle peut correspondre en commençant à Y, et elle correspond à la chaîne laplus courte possible commençant là, donc Y1. La sous-expression [0-9]{1,3} est gourmande mais elle ne peut pas modifier la décision sur la longue de la correspondance ; donc elle est forcée à une correspondance sur simplement 1.

En court, quand une RE contient des sous-expressions gourmandes et non gourmandes, la longueur de correspondance totale est soit aussi longue ou aussi courte que possible, suivant l'attribut affecté à la RE complète. Les attributs affectés aux sous-expressions affectent seulement la quantité de correspondance qu'elles sont autorisées de « manger » par rapport aux autres.

Les quantifieurs {1,1} et {1,1}? peuvent être utilisés pour forcer la gourmandise ou la non gourmandise, respectivement, d'une sous-expression ou de la RE complète. Ceci est utile quand vous avez que la RE complète contienne un attribut de gourmandise différent de celui déduit de ces éléments. Comme exemple, supposez que nous essayons de séparer une chaîne contenant quelques chiffres dans les chiffres et les parties avant et après eux. Nous pourrions essayer de le faire ainsi :

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

Cela n'a pas fonctionné : le premier .* est gourmand donc il « mange » autant qu'il peut, laissant le \d+ correspondre à la dernière place possible, le dernier chiffre. Nous pourrions essayer de corriger cela en le rendant non gourmand :

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

Ceci n'a pas fonctionné non plus parce que, maintenant, la RE entière est non gourmande et donc, elle termine la correspondance globale aussi tôt que possible. Nous pouvons obtenir ce que vous voulons en forçant la RE entière à être gourmande :

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

Contrôler la gourmandise globale de la RE séparément de la gourmandise de ses composants donne plus de flexibilité dans la gestion des motifs de longueur variable.

Lors de la décision sur ce qui est une correspondance longue ou courte, les longueurs des correspondances sont mesurés en caractères, pas en éléments. Toute chaîne vide est considérée plus longue qu'aucune correspondance. Par exemple : bb* correspond au trois caractères du milieu de abbbc ; (week|wee)(night|knights) correspond aux dix caractères de weeknights ; quand (.*).* est comparé à abc, la sous-expression entre parenthèses correspond aux trois caractères ; et quand (a*)* est comparé à bc, la RE complète et la sous-expression entre parenthèses correspond à une chaîne vide.

Si une correspondance indépendante à la casse est demandée, l'effet est comme si toutes les distinctions de casse disparaissaient de l'alphabet. Quand un caractère alphabétique qui existe dans plusieurs 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, par exemple x devient [xX]. Quand il apparaît dans une expression entre crochets, toutes les casses sont ajoutées dans l'expression entre crochets, par exemple [x] devient [xX] et [^x] devient [^xX].

Si une correspondance sensible aux nouvelles lignes est spécifiée, . et les expressions entre crochets utilisant ^ ne correspondront jamais au caractère de nouvelle ligne (pour que les correspondances ne croisent pas les nouvelles lignes sauf si la RE inclut explicitement un saut de ligne) et ^ et $ correspondront à la chaîne vide respectivement après et avant une nouvelle ligne, en plus d'une correspondance en début et en fin de chaîne respectivement. Cependant, les échappements d'ARE \A et \Z continuent de correspondre seulement au début et à la fin de chaine. Également, les raccourcis de classes de caractères \D et \W correspondront à une nouvelle ligne indépendamment de ce mode. (Avant PostgreSQL 14, ils ne correspondaient pas à de nouvelles lignes dans le mode sensible aux nouvelles lignes. Écrire [^[:digit:]] ou [^[:word:]] pour retrouver cet ancien comportement.)

Si la correspondance partielle sensible aux nouvelles lignes est spécifiée, ceci affecte . et les expressions entre crochets comme avec la correspondance sensible à la nouvelle ligne, mais pas à ^ et $.

Si la correspondance partielle inverse sensible aux nouvelles lignes est spécifiée, ceci affecte ^ et $ comme avec la correspondance sensible aux nouvelles lignes, mais pas à . et aux expressions entre crochets. Ceci n'est pas très utile mais est fourni pour la symétrie.

9.7.3.6. Limites et Compatibilités #

Aucune limite particulière n'est imposée sur la longueur des RE dans cette implémentation. Néanmoins, les programmes hautement portablees ne devraient pas employer des RE plus longs que 256 octets, car une implémentation compatible POSIX peut refuser de telles RE.

La seule fonctionnalité des ARE actuellement incompatible avec les ERE POSIX est que \ ne perd pas sa signification spéciale à l'intérieur des expressions entre crochets. Toutes les autres fonctionnalités ARE utilisent une syntaxe illégale ou a des effets non définis ou spécifiés dans les ERE POSIX ; la syntaxe *** des directeurs est en dehors de la syntaxe POSIX pour les BRE et les ERE.

Beaucoup d'extensions ARE sont empruntés de Perl, mais certaines ont été modifiées pour les nettoyer, et quelques extensions Perl ne sont pas présentes. Les incompatibilités de note incluent \b, \B, le manque de traitement spécial pour une nouvelle ligne en fin, l'addition des expressions entre crochets complémentées, les restrictions sur les parenthèses et des références inverses dans les contraintes lookahead/lookbehind et les sémantiques de correspondance pour la correspondance la plus longue/courte (plutôt que la première correspondance).

9.7.3.7. Expressions rationnelles basiques #

Les BRE diffèrent des ERE dans différents aspects. Dans les BRE, |, + et ? sont des caractères ordinaires et il n'existe pas d'équivalent à leur fonctionnalité. Les BRE diffèrent des ERE dans différents aspects. Dans les BRE, |, + et ? sont des caractères ordinaires et il n'existe pas d'équivalent à leur fonctionnalité. Les délimiteurs des limites sont \{ et \}. Les parenthèses pour les sous-expressions imbriquées sont \( and \), with ( et ). ^ est un caractère ordinaire, sauf en début de la RE ou au commencement de la sous-expression entre parenthèses, $ est un caractère standard sauf en fin de RE ou en fin d'une sous-expression entre parenthèses, et * est un caractère standard s'il apparaît au début de la RE ou au début de la sous-expression entre parenthèses (après potentiellement un ^). Enfin, les références inverses d'un simple chiffre sont disponibles, et \< et \> sont des synonymes pour, respectivement, [[:<:]] and [[:>:]]  aucun autre échappement n'est dispn,ible dans le BRE.

9.7.3.8. Differences avec le standard SQL et XQuery #

Depuis SQL:2008, le standard SQL inclut des fonctions et opérateurs pour les expressions rationnelles qui réalise de la correspondance de motif suivant le standard d'expression rationnelle XQuery.

  • LIKE_REGEX

  • OCCURRENCES_REGEX

  • POSITION_REGEX

  • SUBSTRING_REGEX

  • TRANSLATE_REGEX

PostgreSQL n'implémente pas actuellement ces opérateurs et fonctions. Vous pouvez obtenir approximativement des fonctionnalités équivalentes dans chaque cas affichés dans Tableau 9.25. (Différentes clauses optionnelles des deux côtés ont été omises dans cette table.)

Tableau 9.25. Équivalences des fonctions sur les expressions rationnelles

Standard SQLPostgreSQL
string LIKE_REGEX patternregexp_like(string, pattern) ou string ~ pattern
OCCURRENCES_REGEX(pattern IN string)regexp_count(string, pattern)
POSITION_REGEX(pattern IN string)regexp_instr(string, pattern)
SUBSTRING_REGEX(pattern IN string)regexp_substr(string, pattern)
TRANSLATE_REGEX(pattern IN string WITH replacement)regexp_replace(string, pattern, replacement)

Des fonctions d'expression rationnelles similaires à celles fournies par PostgreSQL sont aussi disponibles dans un certain nombre d'autres implémentations SQL alors que les fonctions du standard SQL ne sont pas aussi largement implémentées. Certains détails de la syntaxe des expressions rationnelles pourraient différer dans chaque implémentation.

Les opérateurs et fonctions du standard SQL utilisent les expressions rationnelles XQuery, qui sont très proches de la syntaxe ERA décrite ci-dessus. Les différences notables entre la fonctionnalité existante d'expressions rationnelles POSIX et les expressions rationnelles XQuery incluent :

  • La soustraction de classe d'opérateur XQuery n'est pas supportée. Un exemple de cette fonctionnalité est l'utilisation de la syntaxe suivante pour établir une correspondance avec uniquement des consonnes anglaises : [a-z-[aeiou]].

  • Les raccourcis de classe de caractères 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ères telles que \w (voir Tableau 9.21) 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 de 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 de répondre à plus de variantes de « newline » que POSIX. Les options de correspondance pour la sensibilité aux nouvelles lignes décrites ci-dessus considèrent seulement le code ASCII NL (\n) cmme étant une nouvelle ligne, mais SQL souhaiterait que nous traitions CR (\r), CRLF (\r\n) (une nouvelle ligne pour Windows), et certains caractères uniquement Unicode comme LINE SEPARATOR (U+2028) en tant que nouvelles lignes. Par exemple, . et \s peut compter \r\n comme un seul caractère, et non pas deux, suivant le SQL.

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

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

  • XQuery n'a pas de contraintes lookahead et lookbehind, ni aucun des échappements de contraintes décrits dans Tableau 9.22.

  • Les formes de métasyntaxe décrites dans Section 9.7.3.4 n'existe pas dans XQuery.

  • Les lettres drapeaux des expressions rationnelles définis par XQuery sont en relation mais pas identique aux lettres options pour POSIX (Tableau 9.24). Bien que les options i and q se comportent de la même façon, les autres ne le font pas :

    • Les drapeaux s (permet à un point de correspondre à une nouvelle ligne) et m (autorise ^ et $ à correspondre à de nouvelles lignes) de XQuery donnent accès aux mêmes comportements que les drapeaux n, p et w de POSIX, mais ils ne correspondent pas au comportement des drapeaux s et m de POSIX. Notez en particulier que le point-correspondant-nouvelle-ligne est le comportement par défaut de POSIX mais pas de XQuery.

    • Le drapeau x de XQuery (ignore les espaces blancs dans le motif) est bien différent du drapeau mode étendu de POSIX. Le drapeau x de POSIX permet en plus à # de commencer un commentaire dans le motif, et POSIX n'ignorera pas un caractère espace blanc après un antislash.