Thread Regex-Problem mit Backreferences (44 answers)
Opened by DemoFreak at 2004-02-04 14:37

DemoFreak
 2004-02-04 14:37
#79759 #79759
User since
2003-09-06
54 Artikel
BenutzerIn
[default_avatar]
Hallo zusammen,

ich habe ein kleines Problem mit einer RE, wo ich irgendwie nicht auf die Lösung komme. Gegeben sei eine Textdatei mit Zeilen, die so beginnen:

h040111.233001.gz bfb4e2e0-41f7-71d8-1c34-0aa0093f0000 cb32393c-5603-71d7-1bec-0aa01c1b0000 1 178260287 24 einrechner.einedomain.de 1 178260287 [...]

Die Zeilen enthalten also einige Strings definierter Länge (diese SID-artigen Teile), einige Zahlen und einige Strings variabler Länge, welchen eine Zahl, die ihre Länge ausdrückt, vorangestellt ist (bsplweise der Hostname). Um die Zeilen zu parsen, dachte ich mir, dass ich die Strings variabler Länge in der RE mit einem Konstrukt .{$length} bezeichne, und die Variable $length eine Backref auf das davorstehende Capture der Längenangabe ist. In Worten:

m/h(0401.+)\.gz [a-z0-9\-]{36} [a-z0-9\-]{36} \d+ \d+ (\d+) (.{$2}) .*/;

Das geht nicht. Weder, wenn ich $2 gegen \2 ersetze, noch wenn ich eine vorher "deklarierte" Variable statt der Backref verwende. Mit anderen Worten: wenn ich (?{ $anz=\2 }) hinter dem Ausdruck (\d+) einfüge, wird zwar meine Variable $anz korrekt auf den gecapturedten Wert gesetzt, aber ich kann nicht innerhalb der RE darauf zugreifen, sondern erst danach. Mit einem kleinen Progrämmchen sieht das so aus:

Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/usr/bin/perl

use strict;
#use warnings;
use re 'eval';

my $anz;

open XY, "<test.txt";
while (<XY>) {
   m/h(0401.+)\.gz [a-z0-9\-]{36} [a-z0-9\-]{36} \d+ \d+ (\d+) (?{ print "1. $2"; $anz=$2; print " $anz\n"}) (.{$anz})(?{ print "2. $2\n" }) .*/;
   print "3. $1 $2 $3\n";
}
close XY;


Die Ausgabe ist wie folgt:
hannes@asterix:~> ./testre.pl
1. 24 24
3.
1. 24 24
2. 24
3. 040112.233001 24 einrechner.einedomain.de

Wenn ich (.{$anz}) gegen (.{$2}) oder (.{$+}) austausche, wird selbst im zweiten Durchlauf der String nicht gecaptured, die Ausgabe ist dann so:

hannes@asterix:~> ./testre.pl
1. 24 24
3.
1. 24 24
3.

Wo ist hier mein Denkfehler? Kann man innerhalb einer RE nicht auf seine eigenen Captures zurückgreifen (wäre aber Unsinn, wozu sind sie denn sonst da), oder hab ich mich vertippt? Oder bin ich blond?

Please help! ;) ^^

Gruß, Hannes
Gruss, Hannes

View full thread Regex-Problem mit Backreferences