2016-03-25 15 views
3

Aşağıdaki içeriğe sahip bir metin dosyam var ve perl ile bir dizi veya başka bir veri yapısında iç içe geçmiş işlevleri (rootfunc dahil) ayıklamak istiyorum.iç içe geçmiş işlevleri ve parametreleri almak (metin :: dengeli veya düz perl)

GİRİŞ DOSYA İÇERİĞİ:

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 
    } 
} 

Bütün rootfunc ayıklamak ve benzeri aşağıda çıkışı ile subfunc istiyorum:

AMACI ÇIKIŞ DOSYA (değil,/else da atılacaktır ise) :

sadece rootfunc arasında parantez içinde ne varsa ayıklamak ve ardından subfunc ne varsa alabilirsiniz aşağıdaki gibi perl script ile
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) { 
    } 
} 

ama rootfunc ad/parametreler ve subfunc ad/parametreler kaybolur:

PERL script:

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); 

istenilen çıktıyı almak için herhangi bir yöntem var mı? Teşekkürler,

+0

Eğer tüm ikinci düzey parantez içeriğini kaldırılmasını istiyorum söylemek doğru olur mu? – Borodin

+0

@Borodin Kaldırılması gereken bazı şeyler de birinci seviyede. – laune

+0

Ben de ilk seviye içeriği (adı) istiyorum ... Sadece bazı blahs kaldırılacak –

cevap

2

subfunc anahtar kelimesi olduğu varsayılarak, düzenli bir ifade kullanabilirsiniz. Onu iki s/y'ye böldüm, ama birleştirilebilir. ardından Metin :: regexes ile birlikte kullanılabilir Dengeli

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

orada yuvalanmış ise parantez:

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

teşekkürler, gönderdiğiniz regexs çoğu durumda oldukça iyi çalışır. Ama {} "blah blah" ın içinde çalışırken durdu. Soruyu {} –

+0

içerecek şekilde değiştirdim. Öyleyse, sanırım, alt kümeler içinde de parantez oluşabilir ...() {burada: {} ...} '? – laune

+0

evet, parantez içinde her yerde parantez olabilir –