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?
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;
my $categ_types = join('', keys %categ_hash);
my $categ_types_rx = qr{ \A [$categ_types] \z }x;
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;
return 0;
}
sub process_text {
my ($text, $rule) = @_;
my ($to_replace, $replace_with, $pattern) = split('/', $rule);
my $processed = $text;
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:
Text: mater
Regel: V/N/_
tr/aeiou/12345/
Nach Ersetzung: m1t2r
Text: amna
Regel: [sm]//_[mn]
Nach Ersetzung: ana
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"