Double Commander utilise la bibliothèque gratuite TRegExpr écrite par Andrey Sorokin.
La plupart des explications proviennent du fichier d'aide de cette bibliothèque.
Les expressions régulières sont une méthode largement utilisée pour spécifier des motifs de recherche textuelle. Des caractères spéciaux (métacaractères) permettent de spécifier, par exemple, qu'une chaîne particulière recherchée apparaît au début ou à la fin d'une ligne, ou contient n occurrences d'un caractère ou d'un groupe de caractères.
Double Commander prend en charge les expressions régulières dans les fonctions suivantes :
La bibliothèque TRegExp prend en charge deux modes de fonctionnement : ANSI et Unicode. Lors de la recherche dans des fichiers texte, Double Commander utilise les deux (selon l'encodage du fichier). Lors de la recherche par nom, Unicode est utilisé.
Tout caractère unique correspond à lui-même, sauf s'il s'agit d'un métacaractère ayant une signification particulière décrite ci-dessous.
Une série de caractères correspond à cette même série dans la chaîne cible, ainsi le motif bluh correspondra à bluh dans la chaîne cible.
Nous pouvons forcer l'interprétation littérale des métacaractères ou des séquences d'échappement en les faisant précéder d'une barre oblique inverse \. Par exemple : le métacaractère ^ correspond au début de la ligne, mais \^ correspond au caractère ^, \\ correspond à \, etc.
Voici quelques exemples :
| Exemples de correspondance simple | |
|---|---|
| Expression | Résultat |
foobar |
Correspond à la chaîne foobar |
\^FooBarPtr |
Correspond à ^FooBarPtr |
Les caractères peuvent être spécifiés en utilisant une syntaxe de séquence d'échappement similaire à celle utilisée en C et Perl : \n correspond à un saut de ligne, \t correspond à une tabulation, etc.
Plus généralement, \xnn, où nn est une suite de chiffres hexadécimaux, correspond au caractère ayant la valeur ASCII nn.
Si vous avez besoin de codes de caractères larges (Unicode), vous pouvez utiliser \x{nnnn}, où nnnn représente un ou plusieurs chiffres hexadécimaux.
| Séquences d'échappement | |
|---|---|
| Expression | Résultat |
\xnn |
Caractère avec le code ASCII nn |
\x{nnnn} |
Caractère avec le code ASCII nnnn (un octet pour le texte normal, deux octets pour l'Unicode) |
\t |
Tabulation (HT/TAB), identique à \x09 |
\n |
Saut de ligne (NL/LF), identique à \x0a |
\r |
Retour chariot (CR), identique à \x0d |
\f |
Saut de page (FF), identique à \x0c |
\a |
Alerte (cloche) (BEL), identique à \x07 |
\e |
Échap (ESC), identique à \x1b |
Voici quelques exemples :
| Exemples de séquences d'échappement | |
|---|---|
| Expression | Résultat |
foo\x20bar |
Correspond à foo bar (notez l'espace au milieu) |
\tfoobar |
Correspond à foobar précédé d'une tabulation |
Vous pouvez spécifier une classe de caractères en enfermant une liste de caractères entre [], ce qui correspondra à n'importe quel caractère de la liste.
Si le premier caractère après [ est ^, la classe correspond à tout caractère non contenu dans la liste.
Dans la liste, le caractère - est utilisé pour spécifier une plage, ainsi a-z représente tous les caractères de a à z inclus.
Si vous souhaitez que - soit lui-même membre de la classe, placez-le au début ou à la fin de la liste, ou échappez-le avec une barre oblique inverse.
Si vous souhaitez utiliser ], vous pouvez le placer au début de la liste ou l'échapper avec une barre oblique inverse.
| Classes de caractères | |
|---|---|
| Expression | Résultat |
[-az] |
Correspond à a, z et - |
[az-] |
Correspond à a, z et - |
[a\-z] |
Correspond à a, z et - |
[a-z] |
Correspond aux 26 lettres minuscules de a à z |
[\n-\x0D] |
Correspond à n'importe quel \x10, \x11, \x12, \x13 |
[\d-t] |
Correspond à n'importe quel chiffre, - ou t |
[]-a] |
Correspond à n'importe quel caractère entre ] et a |
Voici quelques exemples :
| Exemples de classes de caractères | |
|---|---|
| Expression | Résultat |
foob[aeiou]r |
Recherche les chaînes foobar, foober, etc., mais pas foobbr, foobcr, etc. |
foob[^aeiou]r |
Recherche les chaînes foobbr, foobcr, etc., mais pas foobar, foober, etc. |
Les métacaractères sont l'essence des expressions régulières, ce sont des caractères spéciaux.
Il existe différents types de métacaractères, comme décrit ci-dessous.
Certaines expressions aident à détecter les séparations de ligne.
| Séparateurs de ligne | |
|---|---|
| Expression | Résultat |
^ |
Début de ligne |
$ |
Fin de ligne |
\A |
Début du texte |
\Z |
Fin du texte |
. |
N'importe quel caractère dans la ligne |
Voici quelques exemples :
| Exemples de séparateurs de ligne | |
|---|---|
| Expression | Résultat |
^foobar |
Correspond uniquement si la chaîne foobar est au début de la ligne |
foobar$ |
Correspond uniquement si la chaîne foobar est à la fin de la ligne |
^foobar$ |
Correspond uniquement si la chaîne foobar est la seule de la ligne |
foob.r |
Correspond à des chaînes comme foobar, foobbr, foob1r, etc. |
Par défaut, le métacaractère ^ garantit uniquement une correspondance au début de la chaîne/du texte d'entrée, et le métacaractère $ uniquement à la fin. Les séparateurs de ligne intégrés ne seront pas mis en correspondance par ^ ou $.
Cependant, vous pourriez vouloir traiter la chaîne comme un tampon multiligne, de sorte que ^ corresponde après tout séparateur de ligne dans la chaîne, et $ corresponde avant tout séparateur de ligne. Vous pouvez y parvenir en activant le modificateur m.
\A et \Z sont comme ^ et $, mais lorsqu'on utilise le modificateur m, ils ne correspondent pas plusieurs fois, alors que ^ et $ correspondront à chaque séparateur de ligne interne.
Par défaut, le métacaractère . correspond à n'importe quel caractère, mais si vous désactivez le modificateur s, . ne correspondra pas aux séparateurs de ligne intégrés.
TRegExpr traite les séparateurs de ligne conformément au standard technique Unicode (Technical Standard #18) :
^ est au début de la chaîne d'entrée, et aussi après toute occurrence de \x0D\x0A ou \x0A ou \x0D si le modificateur m est activé (support Unicode : \x2028 ou \x2029 ou \x0B ou \x0C ou \x85). Notez qu'il n'y a pas de ligne vide dans la séquence \x0D\x0A.
$ est à la fin de la chaîne d'entrée, et aussi avant toute occurrence de \x0D\x0A ou \x0A ou \x0D si le modificateur m est activé (support Unicode : \x2028 ou \x2029 ou \x0B ou \x0C ou \x85). Notez qu'il n'y a pas de ligne vide dans la séquence \x0D\x0A.
. correspond à n'importe quel caractère, mais si le modificateur s est désactivé, . ne correspond pas à \x0D\x0A et \x0A et \x0D (support Unicode : \x2028 et \x2029 et \x0B et \x0C et \x85).
Notez que ^.*$ (motif de ligne vide) ne correspondra pas à une chaîne vide dans la séquence \x0D\x0A, mais correspondra à une chaîne vide dans la séquence \x0A\x0D.
Certaines expressions aident à détecter des groupes de caractères.
| Classes prédéfinies | |
|---|---|
| Expression | Résultat |
\w |
Caractères alphanumériques (y compris _), c'est-à-dire [0-9A-Za-z_] |
\W |
Caractères non alphanumériques |
\d |
Caractères numériques |
\D |
Caractères non numériques |
\s |
N'importe quel caractère d'espacement (identique à [ \t\n\r\f]) |
\S |
Caractères de non-espacement |
Vous pouvez utiliser \w, \d et \s dans vos classes de caractères personnalisées.
Voici quelques exemples :
| Exemples de classes prédéfinies | |
|---|---|
| Expression | Résultat |
foob\dr |
Correspond à des chaînes comme foob1r, foob6r, etc., mais pas foobar, foobbr, etc. |
foob[\w\s]r |
Correspond à des chaînes comme foobar, foob r, foobbr, etc., mais pas foob=r, etc. |
Une limite de mot (\b) est la position entre deux caractères ayant d'un côté \w et de l'autre \W (dans n'importe quel ordre), en comptant les caractères imaginaires au début et à la fin de la chaîne comme correspondant à \W.
| Limites de mots | |
|---|---|
| Expression | Résultat |
\b |
Correspond à une limite de mot |
\B |
Correspond à une non-limite de mot |
Tout élément d'une expression régulière peut être suivi d'un autre type de métacaractère – un itérateur.
En utilisant ces métacaractères, vous pouvez spécifier le nombre d'occurrences du caractère, métacaractère ou sous-expression précédent.
| Itérateurs | |
|---|---|
| Expression | Résultat |
* |
Zéro ou plusieurs fois ("glouton"), similaire à {0,} |
+ |
Une ou plusieurs fois ("glouton"), similaire à {1,} |
? |
Zéro ou une fois ("glouton"), similaire à {0,1} |
{n} |
Exactement n fois ("glouton") |
{n,} |
Au moins n fois ("glouton") |
{n,m} |
Au moins n fois mais pas plus de m fois ("glouton") |
*? |
Zéro ou plusieurs fois ("non glouton"), similaire à {0,}? |
+? |
Une ou plusieurs fois ("non glouton"), similaire à {1,}? |
?? |
Zéro ou une fois ("non glouton"), similaire à {0,1}? |
{n}? |
Exactement n fois ("non glouton") |
{n,}? |
Au moins n fois ("non glouton") |
{n,m}? |
Au moins n fois mais pas plus de m fois ("non glouton") |
Ainsi, les nombres dans les accolades de forme {n,m} spécifient le nombre minimum de correspondances n et le nombre maximum m.
La forme {n} est équivalente à {n,n}, correspondant exactement n fois.
La forme {n,} correspond n fois ou plus.
Il n'y a pas de limite à la taille de n ou m, mais des nombres élevés ralentiront l'exécution et consommeront plus de mémoire.
Si une accolade apparaît dans tout autre contexte, elle est traitée comme un caractère ordinaire.
Voici quelques exemples :
| Exemples d'itérateurs | |
|---|---|
| Expression | Résultat |
foob.*r |
Correspond à des chaînes comme foobar, foobalkjdflkj9r et foobr |
foob.+r |
Correspond à des chaînes comme foobar, foobalkjdflkj9r, etc., mais pas foobr |
foob.?r |
Correspond à des chaînes comme foobar, foobbr et foobr, mais pas foobalkj9r |
fooba{2}r |
Correspond à la chaîne foobaar |
fooba{2,}r |
Correspond à des chaînes comme foobaar, foobaaar, foobaaaar, etc. |
fooba{2,3}r |
Correspond à des chaînes comme foobaar ou foobaaar, mais pas foobaaaar |
Petite explication sur la "gloutonnerie" (greediness).
Un itérateur "glouton" prend autant que possible, un "non glouton" en prend le moins possible.
Par exemple, b+ et b* appliqués à la chaîne abbbbc retournent bbbb, b+? retourne b, b*? retourne une chaîne vide, b{2,3}? retourne bb, b{2,3} retourne bbb.
Vous pouvez basculer tous les itérateurs en mode "non glouton" (voir modificateur g).
Vous pouvez spécifier une série d' alternatives pour un motif en les séparant par |, ainsi fee|fie|foe correspondra à fee, fie ou foe dans la chaîne cible (tout comme f(e|i|o)e).
La première alternative inclut tout depuis le séparateur de motif précédent ((, [ ou le début du motif) jusqu'au premier |, et la dernière alternative inclut tout depuis le dernier | jusqu'au séparateur de motif suivant.
Pour cette raison, il est courant d'enfermer les alternatives entre parenthèses pour minimiser la confusion quant à leur début et leur fin.
Les alternatives sont essayées de gauche à droite, la première alternative qui permet à l'expression entière de correspondre sera choisie.
Cela signifie que les alternatives ne sont pas nécessairement gloutonnes.
Par exemple : lors de la mise en correspondance de foo|foot avec barefoot, seule la partie foo correspondra car c'est la première alternative essayée, et elle a réussi à correspondre à la chaîne cible. (Cela pourrait ne pas avoir d'importance si nous capturons le texte correspondant à l'aide de parenthèses.)
Rappelez-vous également que | est interprété littéralement à l'intérieur des crochets, donc si vous écrivez [fee|fie|foe], vous ne correspondez en fait qu'à [feio|].
Exemple :
| Exemple d'alternatives | |
|---|---|
| Expression | Résultat |
foo(bar|foo) |
Correspond aux chaînes foobar ou foofoo |
La structure entre parenthèses ( ... ) peut également être utilisée pour définir des sous-expressions d'expressions régulières.
Après la recherche, vous pouvez appeler n'importe quelle sous-expression, et vous pouvez également utiliser des sous-expressions comme masques.
Les sous-expressions sont numérotées de gauche à droite dans l'ordre de leur parenthèse ouvrante.
La première sous-expression est numérotée 1, et jusqu'à 90 sous-expressions sont prises en charge (la correspondance de l'expression régulière entière porte le numéro 0 – vous pouvez la remplacer par $0 ou $&).
Voici quelques exemples :
| Sous-expressions | |
|---|---|
| Expression | Résultat |
(foobar){8,10} |
Correspond à une chaîne contenant 8, 9 ou 10 instances de foobar |
foob([0-9]|a+)r |
Correspond à foob0r, foob1r, foobar, foobaar, foobaar, etc. |
Note sur les modèles "Remplacer par" :
$ ou \ littéral dans le modèle, utilisez le préfixe \.1\$ est $2\\rub\\ retournera 1$ est <subexpr2>\rub\.$n, vous devez enfermer n dans des accolades {}.a$12bc retournera a<subexpr12>bc, mais a${1}2bc retournera a<subexpr1>2bc.Exemple :
Inversons la date 21.01.2018 en 2018.01.21 :
Recherche : (\d{2})\.(\d{2})\.(\d{4})
Remplacer par : $3.$2.$1
Les métacaractères \1 à \9 sont interprétés comme des références arrières. \n correspond à la sous-expression n précédemment mise en correspondance.
Voici quelques exemples :
| Exemples de références arrières | |
|---|---|
| Expression | Résultat |
(.)\1+ |
Correspond à aaaa et cc |
(.+)\1+ |
Correspond aussi à abab et 123123 |
(['"]?)(\d+)\1 |
Correspond à "13" (entre guillemets doubles), '4' (entre guillemets simples) ou 77 (sans guillemets), etc. |
Assertion positive lookahead : foo(?=bar) correspond à foo uniquement s'il est suivi de bar, et bar n'est pas inclus dans la correspondance.
Assertion négative lookahead : foo(?!bar) correspond à foo uniquement s'il n'est pas suivi de bar.
Assertion positive lookbehind : (?<=foo)bar correspond à bar uniquement s'il est précédé de foo, et foo n'est pas inclus dans la correspondance.
Assertion négative lookbehind : (?<!foo)bar correspond à bar uniquement s'il n'est pas précédé de foo.
Limitations :
Les parenthèses de lookahead doivent être à la fin de l'expression, et les parenthèses de lookbehind au début de l'expression. Ainsi, les assertions entre choix | ou à l'intérieur de groupes ne sont pas prises en charge.
Pour le lookbehind (?<!foo)bar, l'expression régulière foo doit être de longueur fixe, c'est-à-dire ne contenir que des opérations de correspondance de longueur fixe. Les quantificateurs ne sont pas autorisés, sauf pour les accolades avec des chiffres de répétition {n} ou {n,n}. Les classes de caractères sont autorisées ici, le point est autorisé, \b et \B sont autorisés. Les groupes et les choix ne sont pas autorisés.
Pour les 3 autres types d'assertions, l'expression entre parenthèses peut être de n'importe quelle complexité.
Syntaxe : (?:expr).
Un tel groupe n'a pas d' "index" et est invisible pour les références arrières. Les groupes non capturants sont utilisés lorsque nous voulons regrouper des sous-expressions mais ne voulons pas les enregistrer en tant que partie de correspondance/capture de la chaîne. L'utilisation de groupes non capturants peut accélérer le fonctionnement des expressions régulières.
| Groupes non capturants | |
|---|---|
| Expression | Résultat |
(https?|ftp)://([^/\r\n]+) |
Dans https://doublecmd.sourceforge.io, correspond à https et doublecmd.sourceforge.io |
(?:https?|ftp)://([^/\r\n]+) |
Dans https://doublecmd.sourceforge.io, correspond uniquement à doublecmd.sourceforge.io |
Syntaxe : (?>expr|expr|...).
Les groupes atomiques sont un cas particulier de groupes non capturants : si une partie du motif a déjà été trouvée, ce type de groupement désactive le retour en arrière (backtracking) pour le groupe entre parenthèses. Les groupes atomiques fonctionnent plus rapidement et sont utiles pour optimiser les groupes comportant de nombreuses expressions différentes.
Par exemple, a(bc|b)c correspond à abcc et abc, alors que a(?>bc|b)c correspond à abcc mais pas à abc, car le moteur a l'interdiction de revenir en arrière et d'essayer de régler le groupe sur b.
Le standard Unicode donne des noms aux catégories de caractères. Ce sont des chaînes de 2 lettres. Par exemple, Lu correspond aux lettres majuscules, Ll aux lettres minuscules. Et la grande catégorie de 1 lettre L correspond à toutes les lettres.
| Catégories Unicode | |
|---|---|
| Catégorie | Description |
L | Lettre |
Lu | Lettre majuscule |
Ll | Lettre minuscule |
Lt | Lettre en casse de titre (Title case) |
Lm | Lettre modificatrice |
Lo | Autre lettre |
M | Marque |
Mn | Marque sans espacement |
Mc | Marque de combinaison avec espacement |
Me | Marque d'encadrement |
N | Nombre |
Nd | Chiffre décimal |
Nl | Chiffre lettre |
No | Autre nombre |
P | Ponctuation |
Pc | Ponctuation de connexion |
Pd | Ponctuation de trait d'union |
Ps | Ponctuation d'ouverture |
Pe | Ponctuation de fermeture |
Pi | Ponctuation initiale |
Pf | Ponctuation finale |
Po | Autre ponctuation |
S | Symbole |
Sm | Symbole mathématique |
Sc | Symbole monétaire |
Sk | Symbole modificateur |
So | Autre symbole |
Z | Séparateur |
Zs | Séparateur d'espace |
Zl | Séparateur de ligne |
Zp | Séparateur de paragraphe |
C | Autre |
Cc | Contrôle |
Cf | Format |
Cs | Substitut (Surrogate) |
Co | Usage privé |
Cn | Non attribué |
Le métacaractère \p représente un caractère Unicode de la catégorie spécifiée. Syntaxe : \pL et \p{L} pour les noms de 1 lettre, \p{Lu} pour les noms de 2 lettres.
Le métacaractère \P est l'inverse, il représente un caractère Unicode n'appartenant pas à la catégorie spécifiée.
Ces métacaractères sont également pris en charge à l'intérieur des classes de caractères.
Syntaxe pour un modificateur unique : (?i) pour activer, (?-i) pour désactiver. Plusieurs modificateurs sont autorisés, comme : (?msgxr-imsgxr).
Les modificateurs sont utilisés pour modifier le comportement des expressions régulières. Un modificateur n'affecte que la partie de l'expression régulière située après l'opérateur (?imsgxr-imsgxr).
N'importe lequel de ces modificateurs peut être intégré à l'expression régulière elle-même. Si le modificateur est inséré en ligne dans une sous-expression, il n'affecte que cette sous-expression.
^ et $ pour qu'ils correspondent au début ou à la fin de n'importe quelle ligne à l'intérieur de la chaîne, au lieu de correspondre uniquement au début ou à la fin de la chaîne entière ; voir aussi Séparateurs de ligne. Désactivé par défaut.. pour qu'il corresponde à n'importe quel caractère, même aux séparateurs de ligne (voir aussi Séparateurs de ligne), alors qu'il ne le ferait normalement pas. Activé par défaut.g est désactivé, + fonctionnera comme +?, * comme *?, etc.а-я incluent en plus la lettre russe ё, А-Я inclut Ё, а-Я inclut toutes les lettres russes. Activé par défaut.text est ignoré. Notez que TRegExpr ferme le commentaire dès qu'il rencontre ), il est donc impossible de mettre un ) littéral dans un commentaire.Voici quelques exemples :
| Exemples d'extensions Perl | |
|---|---|
| Expression | Résultat |
(?i)Saint-Petersburg |
Correspond à Saint-petersburg et Saint-Petersburg |
(?i)Saint-(?-i)Petersburg |
Correspond à Saint-Petersburg mais pas à Saint-petersburg |
(?i)(Saint-)?Petersburg |
Correspond à Saint-petersburg et saint-petersburg |
((?i)Saint-)?Petersburg |
Correspond à saint-Petersburg mais pas à saint-petersburg |
Le modificateur x nécessite quelques explications supplémentaires.
Il indique d'ignorer les espaces qui ne sont ni précédés d'une barre oblique inverse ni à l'intérieur d'une classe de caractères.
Vous pouvez l'utiliser pour décomposer une expression régulière en parties (un peu) plus lisibles.
Le caractère # est également traité comme un métacaractère introduisant un commentaire, par exemple :
(
(abc) # commentaire 1
| # vous pouvez utiliser des espaces pour formater l'expression régulière - TRegExpr les ignorera
(efg) # commentaire 2
)
Cela signifie également que si vous souhaitez utiliser un véritable espace ou le caractère # dans un motif (en dehors d'une classe de caractères, où ils ne sont pas affectés par x), vous devez les échapper ou les coder en utilisant des échappements octaux ou hexadécimaux.
Globalement, ces fonctions améliorent considérablement la lisibilité du texte des expressions régulières.