Cet exemple là est basique, mais j'ai besoin de sélectionner une plage de code entre deux accolades distantes de centaines de lignes. Manuellement c'est fastidieux.
Connaîtriez-vous un moyen ?
Il y a entre l'ouverture et la fermeture de ces deux accolades jumelles plusieurs autres accolades imbriquées.
L'expression régulière {.*} ne fonctionne pas dans ce cas là.
Last edit: Cocohen 2014-10-28
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Tout d'abord, saches que les accolades{ et } sont des caractères spéciaux, dans les expressions régulières. Aussi, si tu veux trouver les caractères litteraux accolade ouvrante et fermante, tu dois les faire précéder du caractère antislash, soit \{ et \}.
En guise de test, recopie, dans un nouvel onglet, les 16 lignes ci-dessous. Note que cet ensemble comporte, en tout, 8 accolades ouvrantes et 8 accolades fermantes, placées dans un ordre quelconque !
{
{
}
{
{
{
}
{
}
{
{
}
}
}
}
}
Maintenant :
Replace-toi en début du fichier ( CTRL + Origin )
Ouvre la fenêtre de recherche ( CTRL +F )
Coche l'option de recherche Expression régulière
Décoche, de préférence, la case Boucler
Saisis dans la zone recherche l'expression régulière \{([^{}]|(?0))+\}
Clique sur le bouton Suivant
=> les 16 lignes, constituant un ensemble apparié, avec d'autres blocs {.....} à l'intérieur, sont donc sélectionnées
A présent :
Appuie sur la touche Echap, pour refermer la boîte de recherche
Place le curseur au début de la 2ème ligne
Appuie sur la touche F3 pour rechercher la même regex
=> Cette fois, seules les lignes 2 et 3 son sélectionnées
Puis :
Place le curseur au début de la 3ème ligne
Appuie, à nouveau, sur la touche F3
=> Les lignes 4 à 15, constituant un bloc apparié, sont sélectionnées
Tu peux continuer en plaçant le curseur au début de la 4ème, 5ème,... jusqu'à la 16ème ligne, pour observer l'effet de la regex !
Il est facile de voir que cette expression régulière trouve, à partir de la position actuelle du curseur, la plus GRANDE zone, NON vide, entre 1 accolade ouvrante, incluse, et 1 accolade fermante, incluse, contenant, éventuellement, d'autres blocs {....}, juxtaposés et/ou BIEN imbriqués
NOTE :
On peut décomposer cette expression régulière en :
\{ représente l'accolade ouvrante de début de bloc
[^{}] represente tout caractère unique, différent des accolades. Il peut donc trouver les caractères LF ( \x0a) et CR ( \x0d ) de FIN de ligne, permettant, du même coup, une recherche multi-lignes !
(?0) représente un appel récursif au groupe 0, c'est à dire à la TOTALITE de l'expression régulière, c'est à dire à un bloc {....} ( Voir explication ci-dessous )
[^{}]|(?0) représente donc l'alternative ENTRE 1 caractère unique, NON accolade OU un second bloc interne, de type {....}
([^{}]|(?0))+ représente alors 1 ou PLUS exemplaire(s) de l'alternative précédente
\} représente, enfin, l'accolade fermante de fin de bloc
IMPORTANT :
Les références de groupe (?n)NE sont PAS de même nature que les références arrière \n
(\d+)_\1 trouve les chaînes 01_01 ou 12345_12345 mais PAS les chaînes 01_12345 ni 12345_01
(\d+)_(?1) trouve, par contre, les quatre chaînes ci-dessus, sans exception
En effet :
La référence arrière\1 représente la valeur actuelle du groupe 1 \d+
La référence de groupe(?1) représente le groupe 1, lui-même, c'est à dire \d+
Autrement dit :
La regex (\d+)_\1 trouve 2 nombres identiques, séparés par 1 tiret bas
La regex (\d+)_(?1) trouve 2 nombres quelconques, séparés par 1 tiret bas
Bien sûr, dans le 2ème cas, on aurait pu, tout aussi bien, écrire la regex sous la forme (\d+)_(\d+) !
Lorsque qu'une référence de groupe(?n) est placée à l'INTERIEUR du groupe n, qu'il est censé représenter, elle constitue un appel récursif à ce groupe n. Ceci permet de trouver facilement des structures de blocs, constitués d'un nombre quelconque sous-blocs, complètement appariés, par appels récursifs successifs !
Note que les appels récursifs sont une fonction très puissante des nouveaux moteurs de recherche d'expressions régulières ( dont celui de Notepad++ ! ) mais sont des notions un peu difficiles à appréhender au début !
Si, au contraire, tu désires trouver, à partir de la position actuelle du curseur, la plus PETITE zone, NON vide, entre 1 accolade ouvrante, incluse, et 1 accolade fermante, incluse, NE contenant AUCUN autre bloc {....}, utilises la simple expression régulière \{[^{}]+\}
Amitiés
guy038
P. S. :
Dans un classe de caractères [....], représentant un caractère UNIQUE, la majorité des caractères peuvent être représentés tels quels. Seuls, les 3 caractères tiret (-), antislash (\) et crochet fermant (]) doivent être PRÉCÉDÉS du caractère antislash
Tu trouveras une bonne documentation, de la nouvelle Boost C++ Regex library ( similaire aux PERL Regular Common Expressions ) utilisé par Notepad++, depuis la version 6.0, aux DEUX adresses ci-dessous :
Bonjour à tous,
Je souhaiterais trouver l'expression régulière juste pour sélectionner sous Notepad++ tout ce qu'il y a entre deux accolades jumelles :
http://nsa34.casimages.com/img/2014/10/28/141028035839159141.png
Cet exemple là est basique, mais j'ai besoin de sélectionner une plage de code entre deux accolades distantes de centaines de lignes. Manuellement c'est fastidieux.
Connaîtriez-vous un moyen ?
Il y a entre l'ouverture et la fermeture de ces deux accolades jumelles plusieurs autres accolades imbriquées.
L'expression régulière {.*} ne fonctionne pas dans ce cas là.
Last edit: Cocohen 2014-10-28
Bonjour Cocohen,
Je penses avoir trouvé ce dont tu as besoin :-)
Tout d'abord, saches que les accolades
{
et}
sont des caractères spéciaux, dans les expressions régulières. Aussi, si tu veux trouver les caractères litteraux accolade ouvrante et fermante, tu dois les faire précéder du caractère antislash, soit\{
et\}
.En guise de test, recopie, dans un nouvel onglet, les 16 lignes ci-dessous. Note que cet ensemble comporte, en tout, 8 accolades ouvrantes et 8 accolades fermantes, placées dans un ordre quelconque !
Maintenant :
Replace-toi en début du fichier ( CTRL + Origin )
Ouvre la fenêtre de recherche ( CTRL +F )
Coche l'option de recherche Expression régulière
Décoche, de préférence, la case Boucler
Saisis dans la zone recherche l'expression régulière
\{([^{}]|(?0))+\}
Clique sur le bouton Suivant
=> les 16 lignes, constituant un ensemble apparié, avec d'autres blocs
{.....}
à l'intérieur, sont donc sélectionnéesA présent :
Appuie sur la touche Echap, pour refermer la boîte de recherche
Place le curseur au début de la 2ème ligne
Appuie sur la touche F3 pour rechercher la même regex
=> Cette fois, seules les lignes 2 et 3 son sélectionnées
Puis :
Place le curseur au début de la 3ème ligne
Appuie, à nouveau, sur la touche F3
=> Les lignes 4 à 15, constituant un bloc apparié, sont sélectionnées
Tu peux continuer en plaçant le curseur au début de la 4ème, 5ème,... jusqu'à la 16ème ligne, pour observer l'effet de la regex !
Il est facile de voir que cette expression régulière trouve, à partir de la position actuelle du curseur, la plus GRANDE zone, NON vide, entre 1 accolade ouvrante, incluse, et 1 accolade fermante, incluse, contenant, éventuellement, d'autres blocs
{....}
, juxtaposés et/ou BIEN imbriquésNOTE :
On peut décomposer cette expression régulière en :
\{
représente l'accolade ouvrante de début de bloc[^{}]
represente tout caractère unique, différent des accolades. Il peut donc trouver les caractères LF (\x0a
) et CR (\x0d
) de FIN de ligne, permettant, du même coup, une recherche multi-lignes !(?0)
représente un appel récursif au groupe 0, c'est à dire à la TOTALITE de l'expression régulière, c'est à dire à un bloc{....}
( Voir explication ci-dessous )[^{}]|(?0)
représente donc l'alternative ENTRE 1 caractère unique, NON accolade OU un second bloc interne, de type{....}
([^{}]|(?0))+
représente alors 1 ou PLUS exemplaire(s) de l'alternative précédente\}
représente, enfin, l'accolade fermante de fin de blocIMPORTANT :
Les références de groupe
(?n)
NE sont PAS de même nature que les références arrière\n
(\d+)_\1
trouve les chaînes 01_01 ou 12345_12345 mais PAS les chaînes 01_12345 ni 12345_01(\d+)_(?1)
trouve, par contre, les quatre chaînes ci-dessus, sans exceptionEn effet :
La référence arrière
\1
représente la valeur actuelle du groupe 1\d+
La référence de groupe
(?1)
représente le groupe 1, lui-même, c'est à dire\d+
Autrement dit :
La regex
(\d+)_\1
trouve 2 nombres identiques, séparés par 1 tiret basLa regex
(\d+)_(?1)
trouve 2 nombres quelconques, séparés par 1 tiret basBien sûr, dans le 2ème cas, on aurait pu, tout aussi bien, écrire la regex sous la forme
(\d+)_(\d+)
!Lorsque qu'une référence de groupe
(?n)
est placée à l'INTERIEUR du groupe n, qu'il est censé représenter, elle constitue un appel récursif à ce groupe n. Ceci permet de trouver facilement des structures de blocs, constitués d'un nombre quelconque sous-blocs, complètement appariés, par appels récursifs successifs !Note que les appels récursifs sont une fonction très puissante des nouveaux moteurs de recherche d'expressions régulières ( dont celui de Notepad++ ! ) mais sont des notions un peu difficiles à appréhender au début !
Si, au contraire, tu désires trouver, à partir de la position actuelle du curseur, la plus PETITE zone, NON vide, entre 1 accolade ouvrante, incluse, et 1 accolade fermante, incluse, NE contenant AUCUN autre bloc
{....}
, utilises la simple expression régulière\{[^{}]+\}
Amitiés
guy038
P. S. :
Dans un classe de caractères
[....]
, représentant un caractère UNIQUE, la majorité des caractères peuvent être représentés tels quels. Seuls, les 3 caractères tiret (-
), antislash (\
) et crochet fermant (]
) doivent être PRÉCÉDÉS du caractère antislashTu trouveras une bonne documentation, de la nouvelle Boost C++ Regex library ( similaire aux PERL Regular Common Expressions ) utilisé par
Notepad++
, depuis la version6.0
, aux DEUX adresses ci-dessous :http://www.boost.org/doc/libs/1_48_0/libs/regex/doc/html/boost_regex/syntax/perl_syntax.html
http://www.boost.org/doc/libs/1_48_0/libs/regex/doc/html/boost_regex/format/boost_format_syntax.html
Le PREMIER lien explique la syntaxe, des RegExp, en partie RECHERCHE
Le SECOND lien explique la syntaxe, des RegExp, en partie REMPLACEMENT
Last edit: THEVENOT Guy 2014-11-04