[résolu] regex : extraire entre une paire d'accolades matchées

regex : extraire entre une paire d'accolades matchées [résolu] - Perl - Programmation

Marsh Posté le 18-10-2011 à 07:51:16    

Bonjour
Je travaille en latex, j'ai un fichier .tex dans lequel j'aimerais supprimer toutes les occurences d'une certaine commande (avec un argument) que j'ai créé en la remplaçant par son argument.
Concrètement la commande est :
\newcommand{\corr}[1]{\textbf{#1}}
Elle m'a servi à mettre en gras certaines parties du texte (pour les corriger plus tard) tout en les différenciant dans le .tex des parties qui doivent rester en gras dans le doc final.
 
je pensais m'en sortir avec du Perl pour nettoyer tout ça...
Mais problème : l'argument peut contenir n'importe quel type de caractères y compris des paires d'accolades {} donc je n'arrive pas à le faire continuer jusqu'à la "}" qui matche la première "{" suivant "\corr".
 
Un exemple :
S'il rencontre la chaine "ceci est un exemple \corr{à corriger mais \textbf{cela} doit rester en gras}" je veux qu'il me donne "ceci est un exemple à corriger mais \textbf{cela} doit rester en gras".
 
 
Merci d'avance !
 
(en attendant j'ai surement plus vite fait de les enlever tous à la main dans mon fichier mais cette solution pourrait me reservir plus tard!)
 
 
Edit : en fait mon problème vient plutot de la situation quand il y a plusieurs occurences de cette même chaîne, j'arrive pas à les prendre une à une  :sweat:


Message édité par Argawaen le 18-10-2011 à 14:19:02

---------------
« Before we work on artificial intelligence why don’t we do something about natural stupidity? » Steve Polyak
Reply

Marsh Posté le 18-10-2011 à 07:51:16   

Reply

Marsh Posté le 18-10-2011 à 13:43:57    

Déjà, tu peux faire un \renewcommand{\corr}[1]{#1} en LaTeX pour ne plus être embêté par ta commande, non?
Pour le reste, je vais voir s'il y a une solution simple en Perl, mais j'en doute un peu, les trucs équilibrés dans les regexp, c'est pas si simple.
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 18-10-2011 à 14:09:23    

tout à fait en ce qui concerne l'allure du pdf  
mais comme ce .tex va être amené à circuler auprès de collaborateurs et uploadé sur le net (arxiv), je préfère autant qu'il soit "propre" et qu'on voit pas toutes les bidouilles internes.
 
En tout cas, en fouillant la doc de perlre (http://perldoc.perl.org/perlre.html#Capture-groups) j'ai fini par trouver le morceau de code magique :
 
my $re = qr{ ( \\corr ( \{ ( (?: (?> [^{}]+ ) | (?2) )* ) \} ) ) }x;    
s/$re/$3/;
 
j'ai mis tout ça dans une boucle while qui parcourt mon fichier, quelques conditions et c'est impec!!
2 lignes... Perl superior  :jap:
 

Spoiler :

   
La regex déployée et commentée :
$re = qr{ ( # paren group 1 (full function)
    foo
    ( # paren group 2 (parens)
    \(
    ( # paren group 3 (contents of parens)
    (?:
    (?> [^()]+ ) # Non-parens without backtracking
    |
    (?2) # Recurse to start of paren group 2
    )*
    )
    \)
    )
    )
    }x;
:D


Message édité par Argawaen le 18-10-2011 à 14:11:08

---------------
« Before we work on artificial intelligence why don’t we do something about natural stupidity? » Steve Polyak
Reply

Marsh Posté le 18-10-2011 à 15:12:55    

Oui, ça marche bien:

Code :
  1. #!/usr/local/bin/perl
  2. use strict;
  3. use warnings;
  4.  
  5. my $_ = 'ceci est un \textbf{exemple \corr{a corriger \corr{mais \textbf{ce\corr{la}} doit rester} en gras} fin de} l exemple';
  6. do 1 while (s/(\\corr(\{((?:(?>[^{}]+)|(?2))*)\}))/$3/g);
  7. print "$_\n";

note le $3 plutôt que \3 à la sed dans l'expression de substitution.

C:\Perl>perl balmatch.pl
ceci est un \textbf{exemple a corriger mais \textbf{cela} doit rester en gras fin de} l exemple


 
Je regardais du coté du module Text::Balanced, mais sa doc est loin d'être claire.
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 19-10-2011 à 02:51:47    

Noter aussi que la présence d'un { ou } escapé (\{ ou \}) fait foirer l'expression régulière.
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 12-09-2023 à 17:15:03    

Bonjour je bloque sur un problème très proche : Avez-vous expérimenté Text::Balanced ?  
            $file_contents = <$file>;
            # Tableaux pour stocker les commandes \newcommand et \tikzset
            @newcommands = ();
            @tikzsets = ();
# Premier balayage pour extraire les commandes \newcommand et \tikzset
            # while ($file_contents =~ m/(?:\\newcommand|\\renewcommand)\\[^{}]*\{(?:[^{}]+|(.*))*\}|\\tikzset\{[^{}]+\}/sg)  {
            # do 1 while (s/(\\corr(\{((?:(?>[^{}]+)|(?2))*)\}))/$3/g);
            # while ($file_contents =~ m/(?:\\newcommand|\\renewcommand)\\[^{}]*\{(?:(?>[^{}]+)*)\}|\\tikzset\{[^{}]+\}/sg)  {
      while ($file_contents =~ m/(?:\\newcommand|\\renewcommand)\\[^{}]*\{(?:(?>[^{}]+)*)\}/sg)  {
                $content = $&;
print $content ;  
 
                if ($content =~ /newcommand/) {
                    push @newcommands, $content ;
 print "\n -----------   commande -------- \n" . $content ;  
                }
                elsif ($content =~ /tikzset/) {
                    push @tikzsets, $content ;
# print "\n -----------   Tikzset -------- \n" . $content ;  
                }
            }
Merci d'avance pour le coup de pouce  
 

Reply

Marsh Posté le 13-09-2023 à 17:37:21    

Merci de créer un nouveau topic dédié à ton pb plutôt que déterrer un vieux topic.


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 14-09-2023 à 00:29:30    

et de mettre le code entre balises et d'expliquer un minimum, car les Regex c'est très lisible généralement...


---------------
Si vous ouvrez un sujet merci de ne pas le "laisser mourir" subitement et de le marquer comme "résolu" le cas échéant!
Reply

Marsh Posté le 14-09-2023 à 15:30:26    

Ok J'ai un script qui fonctionne. J'ouvre un nouveau topic. Ce sujet me semble peu traité autant laisser une trace accessible. La suite est là : https://forum.hardware.fr/hfr/Progr [...] 8478_1.htm

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed