Thread Reguläre Ausdrücke suchen
(34 answers)
Opened by Bionerd at 2012-04-18 12:19
Hier mein aktuelles Programm, welches Paare findet, die sich in unterschiedlichen Zeilen befinden, diese schön in Files schreibt zur späteren Verarbeitung.
Code (perl): (dl
)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 #!/usr/bin/perl use strict; use warnings; my $dir='Sequenzen/'; my @motives = ("PO", "OHO", 'G[A-Z]{2}G'); my %anzahl; my $out_dir='Paarungen'; # Ordner öffnen und durchgehen opendir(my $dh, $dir) or die("Error open $dir,($!)\n"); while(my $file=readdir($dh)) { # Pfad machen. my $path="$dir/$file"; # testen ob es eine Datei ist next unless(-f $path); print "Analyse File $file\n"; my %all_match; my @found=analyse_file($path,\@motives); $anzahl{join('-!-', sort @$_[0,1])}++for(@found); printf ( qq("%s" and "%s" found in Line %u and Line %u\n),@$_ ) for(@found); for my $e (@found) { my ($motive1,$motive2)= sort @$e[0,1]; my $outpath="$out_dir/$motive1$motive2.txt"; if(open(my $fh, '>>', $outpath)) { printf $fh ("%s + %s found in Line %u and Line %u + %s\n", @$e,$file); } else { warn("Error open $outpath ($!)"); } } printf ("%s+%s %u\n",split(/-!-/,$_),$all_match{$_}) for (sort keys(%anzahl)); } closedir($dh); ######################################################################## sub analyse_file { my $file=shift; my $motives=shift; # Referenz auf Array #die gesamte Datei einlesen my $content=read_file($file); die("File empty!") unless($content); # eine Liste mit den Positionen der Zeileenden erstellen: my @line_ends=find_lineends($content); # alle Suchbegriffe durchgehen und sich alle Positionen merken. my %match; for my $motive (@$motives) { pos($content)=0; while($content=~/$motive/g) { # zur aktuellen Postion im String wird die Zeile Bestimmt my $line=calculate_line(\@line_ends,pos($content)); # es wird ein Hash of Arrays erstellt push(@{$match{$motive}},$line); } } # Auswertung my @found; my @keys=keys(%match); # jedes Fund mit jedem anderen Kombinieren # doppelte vermeiden for my $p1 (0..$#keys) { my $motive1=$keys[$p1]; for my $p2 ($p1..$#keys) { my $motive2=$keys[$p2]; next if($motive1 eq $motive2 and @{$match{$motive1}}<2); # doppelte ausschließen my %double; for my $line1 (@{$match{$motive1}}) { for my $line2 (@{$match{$motive2}}) { next if($double{"$line1-$line2"}++); next if($double{"$line2-$line1"}++); push(@found,[$motive1,$motive2,$line1,$line2]); } } } } return @found; } sub read_file { my $file=shift; die("ERROR open $file ($!)\n") unless( open(my $handle, '<', $file) ); #zeilenende auf undef setzen local $/=undef; # alles einlesen return <$handle>; } sub calculate_line { my $endings=shift; my $pos=shift; return 0 if($pos<0); return $endings->[-1] if($pos > $endings->[-1]); for my $l (1..$#$endings) { return $l if($pos >= $endings->[$l-1] && $endings->[$l] >= $pos); } return -1; } sub find_lineends { my $content=shift; my @list=(0); my $pos=0; while(( my $p=index($content,"\n",$pos) )>-1) { push(@list,$p); $pos=$p+1; last if($pos>=length($content)); } return @list; } modedit Editiert von pq: more-tags hinzugefügt Last edited: 2012-04-19 09:50:37 +0200 (CEST) |