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

Einträge im Array löschen, auslesen, ..

Leser: 1


<< |< 1 2 >| >> 17 Einträge, 2 Seiten
Gast Gast
 2005-11-21 12:35
#60267 #60267
Hi,

ich habe hier was ziemlich schwieriges (für mich jedenfalls):

Ich habe ein Arry. Der Inhalt sieht z.B. so aus:

Array1 = {'Nr;Name;Vorname;Strasse;Ort',
'1;Bauer;Otto;Heuweg 1;Bonn',
'2;Mueller;Mark;Holzweg 2;Berlin',
'3;Schreiber;Stefan;Hochweg 3;München'}

So, der erste Wert des Arrays ist sozusagen die Überschrift.
Danach kommen jede Menge Einträge.

Ich möchte nun folgendes machen: Die Orte sollen rausgeschmissen werden.
Also: Bonn, Berlin und München (und der ; nach Strasse) sollen gelöscht werden.
(Kann man das evtl. anhand der ; matchen?)

Danach möchte ich die gesamte Überschrift rauswerfen.

Soweit so gut. Und schließlich möchte ich einen einzelnen Eintrag auslesen. Z.B. den "Mueller, Mark". Geht doch bestimmt irgendwie mit: Array1[2] oder?


Danke für eure Hilfe!!!
svenXY
 2005-11-21 14:03
#60268 #60268
User since
2005-09-15
33 Artikel
BenutzerIn
[default_avatar]
Hi,
ist tatsächlich recht einfach. Ich habe jetzt mal nur das gemacht, was Du wolltest:
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
#!/usr/bin/perl -w

use strict;
use Data::Dumper;

my @Array1 = ('Nr;Name;Vorname;Strasse;Ort',
         '1;Bauer;Otto;Heuweg 1;Bonn',
         '2;Mueller;Mark;Holzweg 2;Berlin',
         '3;Schreiber;Stefan;Hochweg 3;Muenchen');

# Ueberschrift wegschmeissen
my $crap = shift @Array1;

print Dumper(\@Array1);

# ; und Ort entfernen
@Array1 = map { m/(.*);.+$/ } @Array1;

print Dumper(\@Array1);

# Element 2 anzeigen
print $Array1[1];

Besser ist es aber sicherlich, jedes Element im Array mittels split() in Teile aufzuspalten, einen Array of Arrays (AoA) zu bauen und dann auf die einzelnen Elemente zuzugreifen.

Gruss,
svenXY
sesth
 2005-11-21 14:29
#60269 #60269
User since
2005-02-01
181 Artikel
BenutzerIn
[default_avatar]
Hallo Ragnar,

hier noch eine Alternative. Zunächst solltest Du wissen, dass Arrays grundsätzlich mit @ beginnen. Die Werteliste wird mit () geklammert und nicht mit {}, da sonst eine Referenz auf einen Hash geliefert wird. Deshalb sieht Dein Array auch etwas anders im Code aus:
Code (perl): (dl )
1
2
3
4
my @Array1 = ('Nr;Name;Vorname;Strasse;Ort',
         '1;Bauer;Otto;Heuweg 1;Bonn',
         '2;Mueller;Mark;Holzweg 2;Berlin',
         '3;Schreiber;Stefan;Hochweg 3;München');

Mit der "shift"-Funktion wird von einer Liste (= Array) das erste Element geliefert und die Liste um das Element verkürzt. Da uns das erste Element nicht interessiert, wird das Ergebnis von shift einfach ignoriert:
Code (perl): (dl )
shift  @Array1;

In einer for-Schleife wird dann der Rest der Liste durchgegangen und mit einem regulären Ausdruck das letzte Element samt Semikolon entfernt.
Code (perl): (dl )
1
2
3
4
5
for (my $i = 0; $i <= $#Array1; $i++) {
    $Array1[$i] =~ s{(;[^;]+)$}{};
}

print $Array1[1];

$#Array1 liefert den Index des letzen Elements des Arrays. Die Lösung mit "map" ist eleganter - aber für einen Anfänger wohl weniger verständlich.
Gruß
Thomas
ragnar
 2005-11-21 15:09
#60270 #60270
User since
2005-11-21
3 Artikel
BenutzerIn
[default_avatar]
Danke euch beiden schon mal!!

Ich hab mich mal an die "map" Methode gewagt, und es funktioniert soweit bis auf eine Kleinigkeit:

Das habe ich geschrieben:

Code: (dl )
map { m/(.*;.*;.*;.*;.*;).*;.*;(.*;.*;.*);.*$/ }


(Sieht besch**** aus ich weiß, muss aber sein, da ich in der Mitte was rauswerfen muss)

So und jetzt schreibt er die 2. Klammer, also (.*;.*;.*) in ein anderes Element als (.*;.*;.*;.*;.*;) !!
Es müssten aber beide in einem Element stehen.

Geht das auch?\n\n

<!--EDIT|ragnar|1132578606-->
betterworld
 2005-11-21 15:27
#60271 #60271
User since
2003-08-21
2614 Artikel
ModeratorIn

user image
Wenn Du nur in der Mitte etwas rauswerfen willst, kannst Du das so machen:
Code: (dl )
map { s/dein lustiger regexp/$1$2/; $_ }


So, wie Du es oben machst, ergibt der Ausdruck im map{} zwei Elemente, und die werden natuerlich auch als zwei behandelt.

Nebenbei solltest Du aber beachten, dass ein Punkt in einem RE auch ein Semikolon treffen kann, und dass Sterne gierig sind. Mehr dazu in perlre\n\n

<!--EDIT|betterworld|1132579790-->
pKai
 2005-11-21 15:35
#60272 #60272
User since
2005-02-18
357 Artikel
BenutzerIn
[default_avatar]
Alternativ benutzt du deinen match folgendermaßen:
Code: (dl )
map { join '' => m/(.*;.*;.*;.*;.*;).*;.*;(.*;.*;.*);.*$/ }

Wenn ich selber einen quick&dirty-Lösung für deine Extraktion schreiben wollte, würde ich allerdings eher so vorgehen:
Code: (dl )
map { join ';' => (split /;/)[0..4,7..9] }


Edit: Wobei mir klar ist, dass beide Varianten nicht dasselbe tun, da dein Regex von hinten die Felder zählt und mein array slice von vorne zählt. Eine direkt äquivalente Form wäre:
Code: (dl )
map { join ';'=>(split /;/)[-(split/;/)..-7,-4..-2] }
:D\n\n

<!--EDIT|pKai|1132580767-->
I sense a soul in search of answers.
ragnar
 2005-11-21 15:44
#60273 #60273
User since
2005-11-21
3 Artikel
BenutzerIn
[default_avatar]
Beides hat funktioniert.

Ihr seid einfach spitze :laugh:
Strat
 2005-11-21 15:50
#60274 #60274
User since
2003-08-04
5246 Artikel
ModeratorIn
[Homepage] [default_avatar]
ja; z.B.
Code: (dl )
1
2
3
4
5
my @array1 = map {
if (m/(.*;.*;.*;.*;.*;).*;.*;(.*;.*;.*);.*$/)
$1 . $2; # rueckgabewert
}
} @array2;
perl -le "s::*erlco'unaty.'.dk':e,y;*kn:ai;penmic;;print"
http://www.fabiani.net/
Strat
 2005-11-21 15:53
#60275 #60275
User since
2003-08-04
5246 Artikel
ModeratorIn
[Homepage] [default_avatar]
[quote=betterworld,21.11.2005, 14:27]
Code: (dl )
@array1 = map { s/dein lustiger regexp/$1$2/; $_ } @array2
[/quote]

Achtung: das veraendert aber auch @array2, weil man die "Laufvariable" $_ veraendert.

wenn man das nicht will, dann besser eine temporaere variable verwenden, z.B.
Code: (dl )
1
2
3
@array1 = map {
(my $x = $_) =~s/dein lustiger regexp/$1$2/; $x
} @array2;
\n\n

<!--EDIT|Strat|1132581249-->
perl -le "s::*erlco'unaty.'.dk':e,y;*kn:ai;penmic;;print"
http://www.fabiani.net/
svenXY
 2005-11-21 16:05
#60276 #60276
User since
2005-09-15
33 Artikel
BenutzerIn
[default_avatar]
Hi,
nur noch mal zu meinem Argument am Anfang: Wenn es darum geht, mehrere verschiedene "Teile" zu extrahieren etc., dann würfde ich das ganze Array umbauen in ein AoA oder ein Array of Hashes (AoH) und dann zugreigfen, auf was immer Du willst.
Etwa so:
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
#!/usr/bin/perl -w

use strict;
use Data::Dumper;

my @Array1 = ('Nr;Name;Vorname;Strasse;Ort',
         '1;Bauer;Otto;Heuweg 1;Bonn',
         '2;Mueller;Mark;Holzweg 2;Berlin',
         '3;Schreiber;Stefan;Hochweg 3;Muenchen');

my @Array2; # hier kommt spter alles rein

# Ueberschrift wegschmeissen
my $crap = shift @Array1;

print Dumper(\@Array1);

for (@Array1) {
  # am semikolon auftrennen
  my($nr,$name,$vorname,$strasse,$ort) = split(/;/);
  
  # als anonymen Hash zuweisen
  push(@Array2, {'nr' => $nr, 'name' => $name, 'vorname' => $vorname, 'strasse' => $strasse});
}

print Dumper(\@Array2);

# auf einzelne Werte zugreifen
print $Array2[1]->{'vorname'} . ' ' . $Array2[1]->{'name'} . "\n";

Gruss,
svenXY
<< |< 1 2 >| >> 17 Einträge, 2 Seiten



View all threads created 2005-11-21 12:35.