Menu

Tout sélectionner entre deux délimiteurs jumeaux

Cocohen
2014-10-28
2014-11-04
  • Cocohen

    Cocohen - 2014-10-28

    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
  • THEVENOT Guy

    THEVENOT Guy - 2014-11-04

    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é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 :

    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