Schrift
[thread]12583[/thread]

Regülarer Ausdrück zu einem hash array

Leser: 2


<< |< 1 2 >| >> 20 Einträge, 2 Seiten
Tom99
 2008-10-04 15:42
#115149 #115149
User since
2008-10-04
10 Artikel
BenutzerIn
[default_avatar]
Hallo,
ich habe gestern mit Perl angefangen und da ich die Sprache sehr intressant finde hab ich micht denk ich mal schon in ein relativ kommpliziertes Thema gestürtzt ich will ein Logfile Parser für ein Spiel machen.
Dabei ist das Datenpaar so aufgebaut:
/ip/127.0.0.1/nickname/Tom......./wasanderes/1235
Da ich aber nie weiss in welcher reinfolge die Datenkommen und was überhaupt alles dabei ist, hätte ich gern ein Hash ?heisst doch so? das wie folgt aus sieht:
%playerinfo{ip} = 127.0.0.1
%playerinfo{nickname} = Tom
usw.

Mit freundlichen Grüßen Tom
pq
 2008-10-04 15:49
#115150 #115150
User since
2003-08-04
12208 Artikel
Admin1
[Homepage]
user image
lies mal Wiki:perlintro, da findest du basis-infos und links auf weitere perldocs,
teilweise auf deutsch übersetzt.
ungestestet:
Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
use Data::Dumper;
my %playerinfo;
if ($logline =~ m{ ^ /ip/ ([^/]+) /nickname/ ([^/]+) /wasanderes/ ([^/]+) }x) {
    my ($ip, $nick, $wasanderes) = ($1, $2, $3);
    $playerinfo{$nick} = {
        ip => $ip,
        wasanderes => $wasanderes,
    };
}
print Dumper \%playerinfo;
Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live. -- Damian Conway in "Perl Best Practices"
lesen: Wiki:Wie frage ich & perlintro Wiki:brian's Leitfaden für jedes Perl-Problem
MatthiasW
 2008-10-04 15:55
#115151 #115151
User since
2008-01-27
367 Artikel
BenutzerIn
[default_avatar]
Ich glaube er sucht eher folgendes:
Code (perl): (dl )
my %player_info = $logline =~ m! /([^/]+)/([^/]+) !xg;

Schließlich hat er ja geschrieben, dass er nicht weiß in welcher Reihenfolge die Daten vorliegen.

MfG
perl -E'*==*",s;;%ENV=~m,..$,,$&+42;e,$==f;$"++for+ab..an;@"=qw,u t,,print+chr;sub f{split}say"@{=} me"'
Tom99
 2008-10-04 16:12
#115152 #115152
User since
2008-10-04
10 Artikel
BenutzerIn
[default_avatar]
Cool, danke ich werd mir die Intro mal durch lesen.
Die Lösung von Matthias war genau das was ich gesucht habe.
Für was steht das m! und das !xg ?
Mhm irgendwie gehts doch nicht so wie ich wollte.
Ich habs jetzt so gelöst:
Code: (dl )
1
2
3
4
5
6
7
	local @array = ($logline =~ /([^\\]+)\\([^\\]+)/g);
local %playerinfo;
for ($i = 0; $i <= @array; $i += 2)
{
$playerinfo{$array[$i]} = $array[$i+1];
}
print Dumper \%playerinfo;
pktm
 2008-10-04 16:19
#115153 #115153
User since
2003-08-07
2921 Artikel
BenutzerIn
[Homepage]
user image
Falls du in der umfangreichen Literatur noch nicht drüber gestoplert bist:
Einen Hash deklarierst du mit %varname, auf einzelne Elemente greifst du aber mit $varname{key} zu. Das Sigil (% bzw. $) ist der Unterschied.
Wenn du also einen Hash erzeugst, dann mahst du das mit dem Prozentzeichen, wenn du auf ein Element zugreifst verwendest du das Dollar-Zeichen.

Edit, scheinste ja schon gefunden zu haben :)
http://www.intergastro-service.de (mein erstes CMS :) )
pktm
 2008-10-04 16:23
#115155 #115155
User since
2003-08-07
2921 Artikel
BenutzerIn
[Homepage]
user image
Tom99+2008-10-04 14:12:17--
Cool, danke ich werd mir die Intro mal durch lesen.
Die Lösung von Matthias war genau das was ich gesucht habe.
Für was steht das m! und das !xg ?
Mhm irgendwie gehts doch nicht so wie ich wollte.
Ich habs jetzt so gelöst:
Code: (dl )
1
2
3
4
5
6
7
	local @array = ($logline =~ /([^\\]+)\\([^\\]+)/g);
local %playerinfo;
for ($i = 0; $i <= @array; $i += 2)
{
$playerinfo{$array[$i]} = $array[$i+1];
}
print Dumper \%playerinfo;


Das sieht seltdam aus. Verwendest du strict und warnings?

Ein Ansatz:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#/usr/bin/perl

use strict;
use warnings;
use Data::Dumper qw/Dumper/;
use FileHandle;

my $ logfile = '/path/2/logfile.log';
my $fh = new FileHandle;
if ($fh->open("< file")) {

while( my $line = $fh->getline() ) {
print "zeile: " . $line; # mal anschauen, was überhaupt in der Zeile steht
# jetzt deinen hash bauen
# deine Arbeit hier :)
}

$fh->close();
}else{
die("Konnte die Datei nicht öffnen: $!");
}
http://www.intergastro-service.de (mein erstes CMS :) )
Tom99
 2008-10-04 16:23
#115156 #115156
User since
2008-10-04
10 Artikel
BenutzerIn
[default_avatar]
Ich hatte mir schon dieses http://perl-seiten.privat.t-online.de/html/perl_ei... Tutorial durschgelesen, jetzt les ich das andere.
Tom99
 2008-10-04 16:25
#115157 #115157
User since
2008-10-04
10 Artikel
BenutzerIn
[default_avatar]
Mein kommpleter Script sah so aus
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
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
#!/usr/bin/perl -w
use Data::Dumper;

use switch;
my $file = "C:/Programme/UrbanTerror/q3ut4/games.log";

open ( FILE, $file ) or die ("Cannt open File $file");

while (defined(my $line = <FILE>))
{
        if ($line =~ /^\s+(\d{1,2}:\d{2}) ((\w+):(?: )?(.*)?)/)
                {
                my $time = $1;
                        if (defined ($3))
                        {
                                if (defined ($4))
                                {
                                        if ($3 eq "ClientConnect")
                                        {
                                                &ClientConnect($4);
                                        }
                                        if ($3 eq "ClientBegin")
                                        {
                                                &ClientBegin($4);
                                        }
                                        if ($3 eq "ClientUserinfo")
                                        {
                                                &ClientUserinfo($4);
                                        }
                                }
                        }
                }
}

sub ClientConnect {
        local $id = shift;
#       print ("Client $id connected\n");
        return 1;
}
sub ClientBegin {
        local $id = shift;
#       print ("Client $id began\n");
        return 1;
}
sub ClientUserinfo {
        local $line = shift;
        if ($line =~ /(\d+) \\(.*)/)
        {
        #print "Client $1: $2\n";
        # HIER SOLL
        local $logline = $2;
        local @array = ($logline =~ /([^\\]+)\\([^\\]+)/g);
        local %playerinfo;
        for ($i = 0; $i <= @array; $i += 2)
                {
                $playerinfo{$array[$i]} = $array[$i+1];
                }
        print Dumper  \%playerinfo;
#       %playerinfo = $logline =~ m! /([^/]+)/([^/]+)/ !xg;
#       print Dumper  \%playerinfo;
        die();
        }
        return 1;
}
MatthiasW
 2008-10-04 16:52
#115158 #115158
User since
2008-01-27
367 Artikel
BenutzerIn
[default_avatar]
Hier mal ein - mangels fehlender games.log - ungetestetes Skript, das funktionieren sollte:
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#!/usr/bin/perl

use strict;
use warnings;

use Data::Dumper;

my $file = 'C:/Programme/UrbanTerror/q3ut4/games.log';

my %proc = (
        'ClientConnect'  => sub{ print "Client $_[0] connected\n" },
        'ClientBegin'    => sub{ print "Client $_[0] began\n"     },
        'ClientUserinfo' => sub{
                my $line = shift;

                if ( $line =~ /(\d+) \\(.*)/ )
                {
                        print "Client $1: $2\n";

                        my $logline     = $2;
                        my %player_info = $logline =~ m! / ([^/]+) / ([^/]+) !xg;

                        print Dumper \%player_info;
                } # if
        },
);

open( my $fh, '<', $file )
        or die "Cannot open file '$file': $!";

while ( my $line = <$fh> )
{
        chomp($line);

        if ( $line =~ /^\s+(\d{1,2}:\d{2}) ((\w+):(?: )?(.*)?)/ )
        {
                #my $time = $1; # findet keine verwendung

                $proc{$3}->($4) if defined $3 and defined $4;
        } # if
} # while

__END__

Ich hab den Teil mit den ifs rausgenommen und durch einen Hash mit Codereferenzen ersetzt, finde ich eleganter.

use switch brauchst du nicht.
Dafür aber use strict und use warnings ;)
Das -w flag hab ich dann auch mal entfernt.

Das m! ... !xg ist [s]eine[/s] ein Regex.
Sieh dir dazu mal in perlop den Matchoperator an.

MfG
perl -E'*==*",s;;%ENV=~m,..$,,$&+42;e,$==f;$"++for+ab..an;@"=qw,u t,,print+chr;sub f{split}say"@{=} me"'
Tom99
 2008-10-04 17:29
#115159 #115159
User since
2008-10-04
10 Artikel
BenutzerIn
[default_avatar]
Hier mal ein Beispiel
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
  2:53 ClientConnect: 0
2:53 ClientUserinfo: 0 \ip\192.168.178.21:27961\challenge\730794036\qport\63353\protocol\68\name\|Affe|Tom\racered\2\raceblue\2\rate\8000\ut_timenudge\0\cg_rgb\128 128 128\funred\phat\funblue\phat\cg_predictitems\0\cg_physics\1\snaps\20\model\sarge\headmodel\sarge\team_model\james\team_headmodel\*james\color1\4\color2\5\handicap\100\sex\male\cl_anonymous\0\gear\GLIARTA\teamtask\0\cl_guid\EE2D5B7EFD8B7DC8C576A5C5B277AFEF\weapmodes\00000110220000020002
2:53 ClientUserinfoChanged: 0 n\|Affe|Tom\t\3\r\2\tl\0\f0\\f1\\f2\\a0\255\a1\255\a2\255
3:00 ClientBegin: 0
3:02 Kill: 0 0 10: |Affe|Tom killed |Affe|Tom by MOD_CHANGE_TEAM
3:02 ClientUserinfo: 0 \ip\192.168.178.21:27961\challenge\730794036\qport\63353\protocol\68\name\|Affe|Tom\racered\2\raceblue\2\rate\8000\ut_timenudge\0\cg_rgb\128 128 128\funred\phat\funblue\phat\cg_predictitems\0\cg_physics\1\snaps\20\model\sarge\headmodel\sarge\team_model\james\team_headmodel\*james\color1\4\color2\5\handicap\100\sex\male\cl_anonymous\0\gear\GLIARTA\teamtask\0\cl_guid\EE2D5B7EFD8B7DC8C576A5C5B277AFEF\weapmodes\00000110220000020002
3:02 ClientUserinfoChanged: 0 n\|Affe|Tom\t\2\r\2\tl\0\f0\phat\f1\\f2\\a0\0\a1\0\a2\255
3:02 ClientBegin: 0
3:14 Item: 1 team_CTF_blueflag
4:16 Flag: 1 2: team_CTF_redflag
4:37 Kill: 0 1 19: |Affe|Tom killed Boa by UT_MOD_LR300
5:23 Item: 0 team_CTF_redflag
5:23 ClientUserinfo: 1 \teamtask\5\sex\male\gear\GLIORAA\team\red\skill\4.000000\characterfile\bots/ut_boa_c.c\color\4\race\2\snaps\20\rate\25000\name\Boa
5:23 ClientUserinfoChanged: 1 n\Boa\t\1\r\2\tl\0\f0\\f1\\f2\\a0\255\a1\0\a2\0
5:32 Item: 1 team_CTF_blueflag
5:32 ClientUserinfo: 1 \teamtask\5\sex\male\gear\GLIORAA\team\red\skill\4.000000\characterfile\bots/ut_boa_c.c\color\4\race\2\snaps\20\rate\25000\name\Boa
5:32 ClientUserinfoChanged: 1 n\Boa\t\1\r\2\tl\0\f0\\f1\\f2\\a0\255\a1\0\a2\0
5:37 ClientUserinfo: 1 \teamtask\5\sex\male\gear\GLIORAA\team\red\skill\4.000000\characterfile\bots/ut_boa_c.c\color\4\race\2\snaps\20\rate\25000\name\Boa
5:37 ClientUserinfoChanged: 1 n\Boa\t\1\r\2\tl\0\f0\\f1\\f2\\a0\255\a1\0\a2\0
5:43 ClientUserinfo: 1 \teamtask\5\sex\male\gear\GLIORAA\team\red\skill\4.000000\characterfile\bots/ut_boa_c.c\color\4\race\2\snaps\20\rate\25000\name\Boa
5:43 ClientUserinfoChanged: 1 n\Boa\t\1\r\2\tl\0\f0\\f1\\f2\\a0\255\a1\0\a2\0
5:48 ClientUserinfo: 1 \teamtask\5\sex\male\gear\GLIORAA\team\red\skill\4.000000\characterfile\bots/ut_boa_c.c\color\4\race\2\snaps\20\rate\25000\name\Boa
5:48 ClientUserinfoChanged: 1 n\Boa\t\1\r\2\tl\0\f0\\f1\\f2\\a0\255\a1\0\a2\0
5:53 ClientUserinfo: 1 \teamtask\5\sex\male\gear\GLIORAA\team\red\skill\4.000000\characterfile\bots/ut_boa_c.c\color\4\race\2\snaps\20\rate\25000\name\Boa
5:53 ClientUserinfoChanged: 1 n\Boa\t\1\r\2\tl\0\f0\\f1\\f2\\a0\255\a1\0\a2\0
5:58 ClientUserinfo: 1 \teamtask\5\sex\male\gear\GLIORAA\team\red\skill\4.000000\characterfile\bots/ut_boa_c.c\color\4\race\2\snaps\20\rate\25000\name\Boa
5:58 ClientUserinfoChanged: 1 n\Boa\t\1\r\2\tl\0\f0\\f1\\f2\\a0\255\a1\0\a2\0
6:04 ClientUserinfo: 1 \teamtask\5\sex\male\gear\GLIORAA\team\red\skill\4.000000\characterfile\bots/ut_boa_c.c\color\4\race\2\snaps\20\rate\25000\name\Boa
6:04 ClientUserinfoChanged: 1 n\Boa\t\1\r\2\tl\0\f0\\f1\\f2\\a0\255\a1\0\a2\0
6:09 ClientUserinfo: 1 \teamtask\5\sex\male\gear\GLIORAA\team\red\skill\4.000000\characterfile\bots/ut_boa_c.c\color\4\race\2\snaps\20\rate\25000\name\Boa
6:09 ClientUserinfoChanged: 1 n\Boa\t\1\r\2\tl\0\f0\\f1\\f2\\a0\255\a1\0\a2\0
6:14 Kill: 1 0 19: Boa killed |Affe|Tom by UT_MOD_LR300
6:14 Flag: 0 0: team_CTF_redflag
6:16 Flag: 1 1: team_CTF_redflag
6:17 Item: 1 ut_weapon_deagle

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
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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#!/usr/bin/perl -w
use Data::Dumper;

use Switch;
my $file = "C:/Programme/UrbanTerror/q3ut4/games.log";

my %players;

open ( FILE, $file ) or die ("Cannt open File $file");


while (defined(my $line = <FILE>))
{
        if ($line =~ /^\s+(\d{1,2}:\d{2}) ((\w+):(?: )?(.*)?)/)
                {
                my $time = $1;
                        if (defined ($3))
                        {
                                if (defined ($4))
                                {
                                        if ($3 eq "ClientConnect")
                                        {
                                                &ClientConnect($4);
                                        }
                                        if ($3 eq "ClientBegin")
                                        {
                                                &ClientBegin($4);
                                        }
                                        if ($3 eq "ClientUserinfo")
                                        {
                                                &ClientUserinfo($4, $time);
                                        }
                                        if ($3 eq "ClientUserinfoChanged")
                                        {
                                                &ClientUserinfoChanged($4);
                                        }
                                }
                        }
                }
}

sub ClientConnect {
        local $id = shift;
#       print ("Client $id connected\n");
        return 1;
}
sub ClientBegin {
        local $id = shift;
#       print ("Client $id began\n");
        return 1;
}
sub ClientUserinfo {
        local ($line,$time) = @_;
        if ($line =~ /(\d+) \\(.*)/)
        {
        #print "Client $1: $2\n";
        # HIER SOLL
        local $id = $1;
        local $logline = $2;
        local @array = ($logline =~ /([^\\]+)\\([^\\]+)/g);
        local %playerinfo;
        for ($i = 0; $i <= @array; $i += 2)
                {
                        if (defined ($array[$i]) && defined ($array[$i+1]))
                        {
                        $playerinfo{$array[$i]} = $array[$i+1];
                        }
                }
                if (defined ($playerinfo{"team"}))
                {
                        
                                if ($playerinfo{"team"} eq "free") {$playerinfo{"team"} = "0";}
                                else if($playerinfo{"team"} eq "red") {$playerinfo{"team"} = "1";}
                                else if ($playerinfo{"team"} eq "blue") {$playerinfo{"team"} = "2";}
                                else {$playerinfo{"team"} = "3";}
                        
                }
        $playerinfo{"id"} = $id;
        $playerinfo{"time"} = $time;
        $players{$id} = \%playerinfo;
        }
        return 1;
}
sub ClientUserinfoChanged{
        local $line = shift;
        #print $line."\n";
        if ($line =~ /(\d+) (.*)/)
        {
        
        local $id = $1;
        local $info = $2;
        local ($name,$team) = ($info =~ /n\\([^\\]+)\\t\\([^\\]+)/);
        $players{$id}{"name"} = $name;
        $players{$id}{"team"} = $team
        }
        return 1
}
        print Dumper \%players;
<< |< 1 2 >| >> 20 Einträge, 2 Seiten



View all threads created 2008-10-04 15:42.