Font
Wiki:Tipp zum Debugging: use Data::Dumper; local $Data::Dumper::Useqq = 1; print Dumper \@var;
[thread]6057[/thread]

Regex-Problem mit Backreferences (page 3)



<< |< 1 2 3 4 5 >| >> 45 entries, 5 pages
Crian
 2004-02-04 18:59
#79779 #79779
User since
2003-08-04
5873 articles
ModeratorIn
[Homepage]
user image
[quote=DemoFreak,04.02.2004, 15:18][quote=Crian,04.02.2004, 15:01]ich würd es trotzdem splitten und das Array dann wieder korrigieren.

Wenn da eine Null steht weißt Du ja, dass ein Element fehlt. Dann füg einfach ein leeres ein.

Wenn da eine 216 steht und das nächste Element keine 216 Elemente hast, spliced Du das übernächste raus und joinst es mit ' ' ans nächste, solange, bis das lang genug ist.[/quote]
Da komm ich jetzt grade nicht ganz mit ;)
Könntest Du mir mal eine Richtung bzw. ein Snippet geben?[/quote]
Ich meinte das so: Erstmal erzeugst Du Dir aus der Zeile mit

Code: (dl )
my @parts = split;


ein Array. Dann weißt Du ja, an welcher Stelle von vorn die erste Längenangabe für den nachfolgenden String kommt. Sagen wir, es ist die sechste Stelle, also Index 5.

Fall 1) $parts[5] = 0

Nun erzeugst Du ein neues Arrayelement mit

Code: (dl )
@parts = (@parts[0..5], '', @parts[6..$#parts]);


Fall 2) $parts[5] > 0

Nun musst Du sehen, ob Dein Teil lang genug ist, bzw. weitere Teile heranziehen:

Code: (dl )
1
2
3
while (length($parts[6]) < $parts[5]) {
   $parts[6] .= ' ' . splice @parts, 7, 1;
}


Nun hast Du diesen Teil gefixt, und Du weist wieder, wo die nächste Nummer bzw. Index ist, die eine Länge des danach folgenden Teiles angibt und wiederholst es für diesen.

Ich würde mir diese Indices in ein Array packen und obiges in einer Schleife von vorn nach hinten durchlaufen lassen. Dadurch, dass die Elemente aufgefüllt bzw. gespliced werden, stimmt dann beim nächsten auch immer wieder Dein Index.

Wenn ich auf Deine Beispielstrings schaue, könnte folgende Liste richtig sein: 5, 9, ... danach weiß ich nicht, welche Nullen Längenangaben sind.

Ich hoffe, das hilft Dir weiter.

Der Code ist nur eine Skizze, kann sein, dass Tipp- oder Denkfehler drin sind. Aber etwas Arbeit sollte ja auch noch bleiben ;)\n\n

<!--EDIT|Crian|1075915520-->
s--Pevna-;s.([a-z]).chr((ord($1)-84)%26+97).gee; s^([A-Z])^chr((ord($1)-52)%26+65)^gee;print;

use strict; use warnings; Link zu meiner Perlseite
DemoFreak
 2004-02-04 19:27
#79780 #79780
User since
2003-09-06
54 articles
BenutzerIn
[default_avatar]
[quote=Crian,04.02.2004, 17:59]Der Code ist nur eine Skizze, kann sein, dass Tipp- oder Denkfehler drin sind. Aber etwas Arbeit sollte ja auch noch bleiben ;)[/quote]
Ich werde das mal beschnarchen, danke :)
Und btw: danke auch für Dein Verständnis dafür, dass ich nicht in Langeweile verfallen möchte... ;) :D
Gruss, Hannes
Crian
 2004-02-04 19:28
#79781 #79781
User since
2003-08-04
5873 articles
ModeratorIn
[Homepage]
user image
Nagut, habs doch mal ausprobiert:

Code: (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
#!/usr/bin/perl
use strict;
use warnings;

my @ind = (1, 6);
local $" = "-";

while (<DATA>) {
print "\n$.: $_";
my @parts = split;

for my $i (@ind) {
print "$.: parts besteht aus ", scalar@parts, " Teilen: @parts\nindex=$i\n";
if ($parts[$i] eq "0") {
@parts = (@parts[0..$i], '', @parts[$i+1..$#parts]);
}
else {
while (length($parts[$i+1]) < $parts[$i]) {
$parts[$i+1] .= ' ' . splice @parts, $i+2, 1;
}
}
}
print "$.: parts besteht aus ", scalar@parts, " Teilen: @parts\n";

print "$.: '$parts[2]', '$parts[7]'\n";
}



_ _DATA_ _
Eintrag_eins 20 dies ist interessant blubb bla fasel 42 /home/dummie/meine datei ist so schoen.txt
Eintrag_zwei 0 blubb bla fasel 14 /root/mein.txt
Eintrag_drei 0 blubb bla fasel 0


Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
1: Eintrag_eins 20 dies ist interessant blubb bla fasel 42 /home/dummie/meine datei ist so schoen.txt
1: parts besteht aus 14 Teilen: Eintrag_eins-20-dies-ist-interessant-blubb-bla-fasel-42-/home/dummie/meine-datei-ist-so-schoen.txt
index=1
1: parts besteht aus 12 Teilen: Eintrag_eins-20-dies ist interessant-blubb-bla-fasel-42-/home/dummie/meine-datei-ist-so-schoen.txt
index=6
1: parts besteht aus 8 Teilen: Eintrag_eins-20-dies ist interessant-blubb-bla-fasel-42-/home/dummie/meine datei ist so schoen.txt
1: 'dies ist interessant', '/home/dummie/meine datei ist so schoen.txt'

2: Eintrag_zwei 0 blubb bla fasel 14 /root/mein.txt
2: parts besteht aus 7 Teilen: Eintrag_zwei-0-blubb-bla-fasel-14-/root/mein.txt
index=1
2: parts besteht aus 8 Teilen: Eintrag_zwei-0--blubb-bla-fasel-14-/root/mein.txt
index=6
2: parts besteht aus 8 Teilen: Eintrag_zwei-0--blubb-bla-fasel-14-/root/mein.txt
2: '', '/root/mein.txt'

3: Eintrag_drei 0 blubb bla fasel 0
3: parts besteht aus 6 Teilen: Eintrag_drei-0-blubb-bla-fasel-0
index=1
3: parts besteht aus 7 Teilen: Eintrag_drei-0--blubb-bla-fasel-0
index=6
3: parts besteht aus 8 Teilen: Eintrag_drei-0--blubb-bla-fasel-0-
3: '', ''


Achtung: $" wird nur zum besseren Ansehen umgesetzt, nicht nachmachen ;-)\n\n

<!--EDIT|Crian|1075916010-->
s--Pevna-;s.([a-z]).chr((ord($1)-84)%26+97).gee; s^([A-Z])^chr((ord($1)-52)%26+65)^gee;print;

use strict; use warnings; Link zu meiner Perlseite
Crian
 2004-02-04 19:34
#79782 #79782
User since
2003-08-04
5873 articles
ModeratorIn
[Homepage]
user image
[quote=DemoFreak,04.02.2004, 18:27][quote=Crian,04.02.2004, 17:59]Der Code ist nur eine Skizze, kann sein, dass Tipp- oder Denkfehler drin sind. Aber etwas Arbeit sollte ja auch noch bleiben ;)[/quote]
Ich werde das mal beschnarchen, danke :)
Und btw: danke auch für Dein Verständnis dafür, dass ich nicht in Langeweile verfallen möchte... ;) :D[/quote]
Urgs, ich hoffe Du bist noch da und ich habe Dich mit meinem Codevorschlag nicht in die Langeweile gestürzt ;-)
s--Pevna-;s.([a-z]).chr((ord($1)-84)%26+97).gee; s^([A-Z])^chr((ord($1)-52)%26+65)^gee;print;

use strict; use warnings; Link zu meiner Perlseite
Crian
 2004-02-04 19:36
#79783 #79783
User since
2003-08-04
5873 articles
ModeratorIn
[Homepage]
user image
Ohne den ganzen Kram zur Testausgabe besteht der Code aus diesem Teil:

Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
my @ind = (1, 6);

while (<DATA>) {
my @parts = split;

for my $i (@ind) {
if ($parts[$i] eq "0") {
@parts = (@parts[0..$i], '', @parts[$i+1..$#parts]);
}
else {
while (length($parts[$i+1]) < $parts[$i]) {
$parts[$i+1] .= ' ' . splice @parts, $i+2, 1;
}
}
}
print "$.: '$parts[2]', '$parts[7]'\n";
}


(Nur falls es dadurch optisch klarer wird...)
s--Pevna-;s.([a-z]).chr((ord($1)-84)%26+97).gee; s^([A-Z])^chr((ord($1)-52)%26+65)^gee;print;

use strict; use warnings; Link zu meiner Perlseite
DemoFreak
 2004-02-04 19:48
#79784 #79784
User since
2003-09-06
54 articles
BenutzerIn
[default_avatar]
[quote=Crian,04.02.2004, 18:34]Urgs, ich hoffe Du bist noch da und ich habe Dich mit meinem Codevorschlag nicht in die Langeweile gestürzt ;-)[/quote]
Nein, in Langeweile keinesfalls.
Ich muss zugeben, dieser Ansatz gefällt mir inzwischen immer besser, obwohl ich weiter oben erst dachte, dass das Splitten und wieder Zusammensetzen eher umständlich wäre. Danke für diese Idee. :)
Gruss, Hannes
DemoFreak
 2004-02-04 22:12
#79785 #79785
User since
2003-09-06
54 articles
BenutzerIn
[default_avatar]
So, eben habe ich das nexte Problem mit dieser Vorgehensweise. Es gibt doch tatsächlich Strings, die am Ende ein Leerzeichen haben. :( Damit läuft nach dem Split, welches das Leerzeichen stillschweigend entsorgt, das Wiederzusammenfügen des Strings genau ein Feld dieses @parts-Arrays zu weit, da die Länge des Strings ohne das hintenanhängende Leerzeichen eben um 1 kleiner ist als die Längenangabe. Dadurch laufe ich auf Fehler bei allen dahinterliegenden Index-Positionen, weil die ja nun plötzlich teilweise keine Zahlen, sondern Strings oder sonstwas enthalten, und das lässt sich nicht mit einer Zahl vergleichen.
Nun habe ich mir schon überlegt, genau diese Warnung abzufangen und zum Anlass zu nehmen, von dem String, der zur vorhergehenden Index-Position gehört, hinten das fälschlicherweise angehängte nächste Element abzuschneiden und wieder in das @parts-Array einzuschieben, aber ich weiss nicht so recht, wie man diese Warnung abfängt.

Die Warnung sieht z.B. so aus:
Code: (dl )
Argument "EventID:" isn't numeric in numeric lt (<) at D:\OVO-Logs\testre.pl line 23, <XY> chunk 100.


Any hints?
Gruss, Hannes
Crian
 2004-02-05 11:19
#79786 #79786
User since
2003-08-04
5873 articles
ModeratorIn
[Homepage]
user image
Hmmm... das ist natürlich sehr ärgerlich. Man könnte folgendes einbauen: Du testest beim Anhängen, ob nur noch 1 Zeichen fehlt. Ist es so, dann musst Du kein neues Element anhängen, sondern ein Leerzeichen zufügen. Ich bau das gerade mal ein...
s--Pevna-;s.([a-z]).chr((ord($1)-84)%26+97).gee; s^([A-Z])^chr((ord($1)-52)%26+65)^gee;print;

use strict; use warnings; Link zu meiner Perlseite
Crian
 2004-02-05 11:23
#79787 #79787
User since
2003-08-04
5873 articles
ModeratorIn
[Homepage]
user image
Code: (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
#!/usr/bin/perl
use strict;
use warnings;

my @ind = (1, 6);
local $" = "-";

while (<DATA>) {
   print "\n$.: $_";
   my @parts = split;

   for my $i (@ind) {
       print "$.: parts besteht aus ", scalar@parts, " Teilen: @parts\nindex=$i\n";
       if ($parts[$i] eq "0") {
           @parts = (@parts[0..$i], '', @parts[$i+1..$#parts]);
       }
       else {
           while (length($parts[$i+1]) < $parts[$i]) {
               if (length($parts[$i+1])+1 == $parts[$i]) {
                   $parts[$i+1] .= ' ';
               }
               else {
                   $parts[$i+1] .= ' ' . splice @parts, $i+2, 1;
               }
           }
       }
   }
   print "$.: parts besteht aus ", scalar@parts, " Teilen: @parts\n";

   print "$.: '$parts[2]', '$parts[7]'\n";
}




Eintrag_eins 20 dies ist interessant blubb bla fasel 42 /home/dummie/meine datei ist so schoen.txt
Eintrag_zwei 0 blubb bla fasel 14 /root/mein.txt
Eintrag_drei 0 blubb bla fasel 0
Eintrag_vier 20 dies ist interessan  blubb bla fasel 42 /home/dummie/meine datei ist so schoen.txt


Ausgabe (man beachte Fall 4):

Code: (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
1: Eintrag_eins 20 dies ist interessant blubb bla fasel 42 /home/dummie/meine datei ist so schoen.txt
1: parts besteht aus 14 Teilen: Eintrag_eins-20-dies-ist-interessant-blubb-bla-fasel-42-/home/dummie/meine-datei-ist-so-schoen.txt
index=1
1: parts besteht aus 12 Teilen: Eintrag_eins-20-dies ist interessant-blubb-bla-fasel-42-/home/dummie/meine-datei-ist-so-schoen.txt
index=6
1: parts besteht aus 8 Teilen: Eintrag_eins-20-dies ist interessant-blubb-bla-fasel-42-/home/dummie/meine datei ist so schoen.txt
1: 'dies ist interessant', '/home/dummie/meine datei ist so schoen.txt'

2: Eintrag_zwei 0 blubb bla fasel 14 /root/mein.txt
2: parts besteht aus 7 Teilen: Eintrag_zwei-0-blubb-bla-fasel-14-/root/mein.txt
index=1
2: parts besteht aus 8 Teilen: Eintrag_zwei-0--blubb-bla-fasel-14-/root/mein.txt
index=6
2: parts besteht aus 8 Teilen: Eintrag_zwei-0--blubb-bla-fasel-14-/root/mein.txt
2: '', '/root/mein.txt'

3: Eintrag_drei 0 blubb bla fasel 0
3: parts besteht aus 6 Teilen: Eintrag_drei-0-blubb-bla-fasel-0
index=1
3: parts besteht aus 7 Teilen: Eintrag_drei-0--blubb-bla-fasel-0
index=6
3: parts besteht aus 8 Teilen: Eintrag_drei-0--blubb-bla-fasel-0-
3: '', ''

4: Eintrag_vier 20 dies ist interessan  blubb bla fasel 42 /home/dummie/meine datei ist so schoen.txt
4: parts besteht aus 14 Teilen: Eintrag_vier-20-dies-ist-interessan-blubb-bla-fasel-42-/home/dummie/meine-datei-ist-so-schoen.txt
index=1
4: parts besteht aus 12 Teilen: Eintrag_vier-20-dies ist interessan -blubb-bla-fasel-42-/home/dummie/meine-datei-ist-so-schoen.txt
index=6
4: parts besteht aus 8 Teilen: Eintrag_vier-20-dies ist interessan -blubb-bla-fasel-42-/home/dummie/meine datei ist so schoen.txt
4: 'dies ist interessan ', '/home/dummie/meine datei ist so schoen.txt'


Das müsste so klappen, denn wenn genau ein Zeichen fehlt, dann muss es ein Leerzeichen am Ende sein. Problematisch wird es nur, wenn Du meldungen mit mehreren Leerzeichen am Ende hast. Dann muss man ggf. irgendwie versuchen, diese zu erkennen oder doch eine andere Methode anwenden. Die liefe dann aber schon auf eine "echte" Textanalyse hinaus.

Edit: Mir fällt gerade auf, man könnte den Code noch beschleunigen (mehrfach verwendete Arrayelemente in Extravariable speicehrn und häufigen Fall in die If-Abfrage und seltenen in den Else-Zweig etc. Aber sowas sollte man nur machen, wenn dies wirklich ein Flaschenhalscodestück sein sollte. Wenn es das ist, sag Bescheid, dann schaue ich es mir daraufhin nochmal an. Anderenfalls gilt das Gebot der Optimierung: Nicht zu optimieren wo es nicht nötig ist.\n\n

<!--EDIT|Crian|1075973266-->
s--Pevna-;s.([a-z]).chr((ord($1)-84)%26+97).gee; s^([A-Z])^chr((ord($1)-52)%26+65)^gee;print;

use strict; use warnings; Link zu meiner Perlseite
DemoFreak
 2004-02-05 12:20
#79788 #79788
User since
2003-09-06
54 articles
BenutzerIn
[default_avatar]
Ich verfolge jetzt erstmal kurz einen anderen Ansatz, da mir aufgefallen ist, dass ich zum einen ja nicht garantieren kann, dass nicht doch mal mehrere Leerzeichen am Ende stehen, und zum anderen der Fall aufgetreten ist, dass diese Strings auch Zeilenschaltungen enthalten (also mehrzeilige Kommentare etc.), und sobald nach einer solchen Zeilenschaltung vielleicht eine Einrückung steht, hätte ich auch wieder dasselbe Problem.
Ich melde mich dann nochmal, wenn ich mit dem anderen Ansatz auf die Nase gefallen bzw. zum Ziel gekommen bin. :)
Gruss, Hannes
<< |< 1 2 3 4 5 >| >> 45 entries, 5 pages



View all threads created 2004-02-04 14:37.