2016-03-25 5 views
3

Ich habe eine Textdatei mit folgendem Inhalt und möchte verschachtelte Funktionen (einschließlich rootfunc) in einem Array oder einer anderen Datenstruktur mit Perl extrahieren.perl geschachtelte Funktionen und Parameter (text :: balanced oder plain perl)

INPUT FILE INHALT:

rootfunc aaa with string1 { 
    blah blah 
    subfunc bbb (different parameters) { 
     blah blah 
    } 
    subfunc others_in_aaa (different parameters) { 
     blah blah 
    } 
} 

rootfunc ccc with string2 { 
    blah blah 
    if (blah) { 
     blah blah 
    } else { 
     blah blah 
    } 
    subfunc others_in_ccc (different parameters) { 
     blah blah 
    } 
} 

rootfunc others with stringothers { 
    blah blah 
    subfunc others_in_others (different parameters) { 
     blah blah 
    } 
} 

ich alle rootfunc extrahieren möchte und subfunc mit dem Ausgang wie unten:

BESTIMMT OUTPUT FILE (nicht, wird die if/else auch zu) :

rootfunc aaa with string1 { 
    subfunc bbb (different parameters) { 
    } 
    subfunc others_in_aaa (different parameters) { 
    } 
} 

rootfunc ccc with string2 { 
    subfunc others_in_ccc (different parameters) { 
    } 
} 

rootfunc others with stringothers { 
    subfunc others_in_others (different parameters) { 
    } 
} 

Mit dem perl-Skript wie folgt kann ich nur extrahieren, was in der Klammer von rootfunc ist und dann bekommen, was in subfunc ist, aber die rootfunc Name/Parameter und subfunc Name/Parameter sind verloren:

Perlskript:

use Text::Balanced qw(extract_multiple extract_bracketed); 

open(FILE, "/tmp/a") || die "Unable to open /tmp/a: $!\n"; 
{ 
    local $/=undef; 
    my $file = <FILE>; 
} 
close(FILE); 
my @array = extract_multiple($file, [sub{extract_bracketed($_[0], '{}')},], undef, 1); 

Gibt es eine Methode, um die gewünschte Ausgabe zu erhalten? Danke,

+0

Wäre es richtiger zu sagen, dass Sie die Inhalte aller Second-Level-Klammern entfernt werden? – Borodin

+0

@Borodin Einige Blabla zu entfernen ist auch auf der Ebene eins. – laune

+0

Ich möchte den Inhalt der ersten Ebene (Name) auch ... Nur ein paar Blahs entfernt werden –

Antwort

2

Angenommen, dass subfunc ein Schlüsselwort ist, können Sie einen regulären Ausdruck verwenden. Ich habe es in zwei s /// aufgeteilt, aber es kann kombiniert werden.

sub squeeze { 
    my($s) = @_; 
    $s =~ s/(?<=\{\n)[^(){}]*?(?= *subfunc)//sg; 
    $s =~ s/(?<=\{)[^(){}]*?(?=\})//sg; 
    return $s; 
} 

Wenn es verschachtelte Klammern dann Text :: Balanced kann mit regulären Ausdrücken in Kombination miteinander verwendet werden:

sub squeeze { 
    my($s) = @_; 
    my $out = ''; 
    while($s =~ s/^(\s*rootfunc[^{]*\{).*?(?=\s*subfunc)//s){ 
     $out .= $1 ; 
     while($s =~ s/^(\s*subfunc[^)]+\)\s*).*?(?=\{)//s){ 
      $out .= $1; 
      my($ext, $rem) = extract_bracketed($s, '{'); 
      $out .= "{}"; 
      $s = $rem; 
     } 
     $out .= "}"; 
     if($s =~ s/^(\s+\})//s){ 
      $s .= $1; 
     } 
    } 
    return $out; 
} 
+0

Danke, die Regexs, die Sie gepostet Arbeit ziemlich gut in den meisten Fällen. Aber es funktioniert nicht mehr, wenn {} in "blah blah" ist. Ich habe die Frage so modifiziert, dass sie {} enthält –

+0

Dann, ich nehme an, geschweifte Klammern können auch in 'subfunc ...() {here: {} ...}'? – laune

+0

Ja, Hosenträger können überall in der Blabla –

Verwandte Themen