Thread Nur einen Buchstaben in Buchstabenkombination ersetzen
(15 answers)
Opened by Gast at 2012-11-17 17:22
Dein zweites Problem hätte mit dem Skript schon funktioniert, wäre dieses fehlerfrei gewesen ;) Die Bearbeitung von $pattern in der sub muss in drei Schritte zerlegt werden (vgl. edit).
Deine erste Frage ist ein Fall für tr///, allerdings musst Du beachten, dass hier keine Variableninterpolation stattfindet, daher die eval-Konstruktion. Um diesen Sonderfall abzubilden, werden die Kategorien erst in einem Hash abgelegt, so dass man aus den keys ein Suchmuster bauen kann, das alle Kategorie-Typen enthält. Jetzt kannst Du natürlich jeden Sonderfall einzeln programmieren. Sinnvoll wäre es, zuerst die Benutzerschnittstelle (erlaubte Eingaben) wirklich festzulegen. Einzelfall-Programmierung ist immer schlecht zu ändern/erweitern. Alles ist nach wie vor ohne Fehlerprüfungen! Es ist insbesondere sehr problematisch, User-Eingaben direkt als RegEx zu verwenden, wer böse ist, kann Dir hier einiges ruinieren. Ein gescheites Parsen der Eingaben ist also unabdingbar! btw: Was machst Du, wenn "normale" Großbuchstaben mit Deinen Kategorien kollidieren? 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 use warnings; use strict; $| = 1; my @categories = ( 'V=aeiou', 'P=pbtdkg', 'N=12345' ); my %categ_hash = map { split /=/ } @categories; # ('V' => 'aeiou', ...) my $categ_types = join('', keys %categ_hash); # 'VPN' my $categ_types_rx = qr{ \A [$categ_types] \z }x; # \A[VPN]\z while (1) { print "Text: "; my $text = <STDIN>; chomp($text); last if ! $text; print "Regel: "; my $rule = <STDIN>; chomp($rule); last if ! $rule; my $rule_err = rule_check($rule); if ($rule_err) { print "Regel fehlerhaft: $rule_err\n"; next; } my $processed_text = process_text($text, $rule); print "\nNach Ersetzung: $processed_text\n\n"; } sub rule_check { my $rule = shift; # Hier Regelsyntax prüfen! return 0; # fehlerfrei } sub process_text { # build_regex($rule); my ($text, $rule) = @_; my ($to_replace, $replace_with, $pattern) = split('/', $rule); my $processed = $text; # Sonderfall translate (z.B. Regel V/N/_), das $pattern wird ignoriert if ($to_replace =~ $categ_types_rx and $replace_with =~ $categ_types_rx) { $to_replace = $categ_hash{$to_replace}; $replace_with = $categ_hash{$replace_with}; print ("tr/$to_replace/$replace_with/\n"); if (length($to_replace) != length($replace_with)){ warn "Ungleiche Zeichenzahl in Kategorien.\n"; } else { local $_ = $processed; eval "tr/$to_replace/$replace_with/"; $processed = $_; } return $processed; } for my $category (@categories) { my ($type, $class) = split('=', $category); $pattern =~ s/$type/[$class]/g; $to_replace =~ s/$type/[$class]/g; } $pattern =~ s/(.+)_/(?<=$1)_/; $pattern =~ s/_(.+)/_(?=$1)/; $pattern =~ s/_/$to_replace/; $processed =~ s/$pattern/$replace_with/g; return $processed; } __END__ Alles wie gesagt noch sehr schlicht. Denkbar wären z.B. noch Regeln wie V/N/_P (bislang wird das '_P' ignoriert, viel Spaß beim Programmieren :) Beispiele: Code: (dl
)
1 Text: mater Editiert von FIFO: typo Last edited: 2012-11-18 09:06:41 +0100 (CET) Everyone knows that debugging is twice as hard as writing a program in the first place. So if you're as clever as you can be when you write it, how will you ever debug it? -- Brian Kernighan: "The Elements of Programming Style"
|