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

String splitten: attention, newbie detected!



<< >> 7 Einträge, 1 Seite
miodio
 2006-05-31 13:50
#66822 #66822
User since
2006-05-31
3 Artikel
BenutzerIn
[default_avatar]
also erstens will ich nur mal schnell anfügen, dass ich diese woche mit perl angefangen hab, deshalb zerreist mich nich.


das script soll die $muh variable in <DIR> folder zerschnipseln, was eigentlich wunderbar funktioniert aber geht das nicht auch einfacher? der code kommt mir ganz schön lang vor.

Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
use warnings;
use strict;

my $muh = "10-22-03 10:04AM 3815 bitte_lesen.txt05-30-06 02:36PM <DIR> database04-06-05 01:53PM 68924 desk.JPG05-07-05 05:07PM 159808 KNAPP.JPG05-01-06 12:52AM <DIR> logfiles02-08-06 10:14PM <DIR> public_html12-19-05 01:01AM <DIR> stats";

my @inhalt = split(/\s+/, $muh);

my $i = 0;
my $g;
my %hash;
my $whatsin;

while ($inhalt[$i]) {
$g = $i + 1;
$whatsin = $inhalt[$i];
if ($whatsin eq '<DIR>') {
%hash = ($inhalt[$i] => $inhalt[$g]);
print "$hash{'<DIR>'}\n";
}
$i++;
}



ach ja, das resultat ist trotzdem nicht ganz zufriedenstellend:
Code: (dl )
1
2
3
4
database04-06-05
logfiles02-08-06
public_html12-19-05
stats


ich weiss leider nur nicht, wie ich das datum entfernen kann. ein paar tipps wären sehr hilfreich.
danke schonmal ;)
Taulmarill
 2006-05-31 14:02
#66823 #66823
User since
2004-02-19
1750 Artikel
BenutzerIn

user image
kürzer geht's schon, ist nur die frage ob das dann einfacher zu versetehen ist. ich würde das folgendermassen lösen (wenn ich jetzt die anforderungen richtig verstanden habe):
Code: (dl )
1
2
3
4
5
6
7
8
9
use warnings;
use strict;

my $muh = "10-22-03 10:04AM 3815 bitte_lesen.txt05-30-06 02:36PM <DIR> database04-06-05 01:53PM 68924 desk.JPG05-07-05 05:07PM 159808 KNAPP.JPG05-01-06 12:52AM <DIR> logfiles02-08-06 10:14PM <DIR> public_html12-19-05 01:01AM <DIR> stats";

for my $file ( $muh =~ /<DIR>\s*([\w.-]+)/g ) {
$file =~ s/\d\d-\d\d-\d\d$//;
print "$file\n";
}

du solltest als nächstes evtl. mal was über Reguläre Ausdrücke lesen.
$_=unpack"B*",~pack"H*",$_ and y&1|0& |#&&print"$_\n"for@.=qw BFA2F7C39139F45F78
0A28104594444504400 0A2F107D54447DE7800 0A2110453444450500 73CF1045138445F4800 0
F3EF2044E3D17DE 8A08A0451412411 F3CF207DF41C79E 820A20451412414 83E93C4513D17D2B
miodio
 2006-05-31 14:23
#66824 #66824
User since
2006-05-31
3 Artikel
BenutzerIn
[default_avatar]
danke, genau was ich suchte, funktioniert wunderbar ;) jedoch habe ich noch einige fragen:

Code: (dl )
 $file ( $muh =~ /<DIR>\s*([\w.-]+)/g ) { 

<dir> leerzeichen_1_oder_mehr_mal ([wortzeichen".""-"] 1_oder_mehr_mal ) /g ) ?

was bedeutet /g?
die anderen ausdrücke kannte ich, hoffe ich zumindest aber g ist mir fremd und konnte ich auch grad nirgends finden.

und ich verstehe nicht, warum er mehrer zeilen ausgibt, da is doch gar keine schleife dabei?
Code: (dl )
1
2
3
4
for my $file ( $muh =~ /<DIR>\s*([\w.-]+)/g ) {
$file =~ s/\d\d-\d\d-\d\d$//;
print "$file\n";
}



*edit
ich bin blind, habs erst jetzt gesehen..
g hab ich auch gefunden
;)\n\n

<!--EDIT|miodio|1149071861-->
Taulmarill
 2006-05-31 15:04
#66825 #66825
User since
2004-02-19
1750 Artikel
BenutzerIn

user image
den regex hast du ganz richtig verstanden. ich habe mir eben noch eine abwandlung überlegt
Code: (dl )
for my $file ( $muh =~ /<DIR>\s*([^\s]+)/g ) {

mit [^] gibt man nicht eine liste der gesuchen zeichen, sondern der nicht gesuchen zeichen an. oder anders formuliert, er nimmt jetzt alles, was kein leerzeichen ist. damit kann man auch exotische zeichen in den verzeichnissnamen verwenden.
$_=unpack"B*",~pack"H*",$_ and y&1|0& |#&&print"$_\n"for@.=qw BFA2F7C39139F45F78
0A28104594444504400 0A2F107D54447DE7800 0A2110453444450500 73CF1045138445F4800 0
F3EF2044E3D17DE 8A08A0451412411 F3CF207DF41C79E 820A20451412414 83E93C4513D17D2B
miodio
 2006-05-31 17:48
#66826 #66826
User since
2006-05-31
3 Artikel
BenutzerIn
[default_avatar]
danke nochmal taulmarill

aber ich hab jetzt lange an der for schleife rumstudiert, nur komme ich auf keinen grünen zweig. ich versuche mal die schleife wörtlich aufzulösen, vielleicht kann mir ja jemand das fehlende erklären und mich ggbf korrigieren.
hoffentlich macht sich überhaupt jemand die mühe, das hier alles durch zu lesen.

erstens mal die theorie, die ich in einem tutorial gelesen habe
Code: (dl )
1
2
3
for (Initialisierungsausdruck; Bedingung; Reinitialisierungsbefehl) {     # Schleifenkopf
Befehl; # Schleifenkörper
}


nochmal das script
Code: (dl )
for my $file ( $muh =~ /<DIR>\s*([^\s]+)/g ) {


schleifenkopf
ich würde jetzt einfach mal sagen, dass der initialisierungsaudruck my $file ist, die bedinung ($muh =~ "regex") und der reinitialisierungsbefehl wird anscheinend nicht benötigt.
also:
so lange <dir> leerzeichen ([nicht_leerzeichen]ein_oder_mehrmals)global vorhanden, wird der schliefenkörper ausgeführt.
wobei mich der ausdruck global ein wenig verwirrt

Code: (dl )
1
2
3
   $file =~ s/\d\d-\d\d-\d\d$//;
print "$file\n";
}

schleifenkörper
suche in $file zahl_zahl_"-"_zahl_zahl_"-"_zahl_zahl_$/ und ersetze es mit nichts
print is mir klar :P
$ musste ich nachschauen, kannte ich bis jetzt auch nicht

Quote
Das Dollarzeichen kann einen Skalar einleiten oder bei Zeichenketten angeben, dass das voranstehende Suchmuster am Ende des Suchbereichs vorkommen muss.


nur welcher skalar wird eingeleitet? $muh?
aber macht irgendwie keinen sinn, dann würde doch der name der ordner, die ich eigentlich "printen" will, gelöscht?
hm.. ja, das wars erstma ;)
Dubu
 2006-05-31 23:11
#66827 #66827
User since
2003-08-04
2145 Artikel
ModeratorIn + EditorIn

user image
Dein Tutorial war wohl nicht vollständig.

Es gibt in Perl zwei for-Schleifen. Erstens die "C-ähnliche" Schleife, deren Syntax du oben aufgeschrieben hast. Und zweitens die Schleife über eine Liste:

  for skalar (liste) { ... }

Die liste kann dabei auch ein Array sein. Beispiel:
Code: (dl )
1
2
3
for my $element (@array) {
   print $element;
}

Bei dieser Schleife ist $element nacheinander ein Alias für alle Elemente von @array, d.h. es enthält nacheinander die Werte von @array, und wenn man $element etwas zuweist, dann wird das entsprechende Element in @array geändert.

Man kann $element auch noch weglassen, dann übernimmt die Defaultvariable $_ die Funktion:
Code: (dl )
1
2
for (@array) {
   print;       # ist das Gleiche wie "print $_"


Die gleiche Funktion kann man auch mit der anderen for-Schleife erreichen, aber es ist a) länger, b) unübersichtlicher und c) fehlerträchtiger:
Code: (dl )
1
2
3
for (my $i = 0; $i <= $#array; ++$i) {
   print $array[$i];
}

($#array ist der Index des letzten Elementes in @array.)

Im obigen Fall wird die Liste, über die die Schleife geht, durch den Ausdruck
Code: (dl )
$muh =~ /<DIR>\s*([^\s]+)/g

geliefert. Wenn so ein Pattern Match mit einem /g am Ende im Listenkontext steht, dann besteht die Liste aus allen Treffern, die sich im String (hier $muh) finden lassen.


Ich denke, du solltest dir mal ein besseres Tutorial anschauen. Vielleicht findest du etwas geeignetes unter Wiki:Wissensbasis.PerlWebSites. Wir empfehlen gerne Strats "Einführung in Perl". :)
Linuxer
 2006-06-01 00:36
#66828 #66828
User since
2006-01-27
3891 Artikel
HausmeisterIn

user image
Hi,

kleine Korrektur und Anmerkung...

\s* bezeichnet _kein_ oder mehr Leerzeichen und ist ein Unterschied zu \s+, welches _ein_ oder mehr Leerzeichen meint.

@Taulmarill:
warum nimmst Du kein \S anstelle des [^\s]?
Schreibt sich einfacher und meint das gleiche ;o)\n\n

<!--EDIT|Linuxer|1149107980-->
meine Beiträge: I.d.R. alle Angaben ohne Gewähr und auf Linux abgestimmt!
Die Sprache heisst Perl, nicht PERL. - Bitte Crossposts als solche kenntlich machen!
<< >> 7 Einträge, 1 Seite



View all threads created 2006-05-31 13:50.