Schrift
[thread]9966[/thread]

Benötige Hilfe bei RegEx (Seite 2)

Leser: 1


<< |< 1 2 >| >> 18 Einträge, 2 Seiten
PerlProfi
 2007-08-05 01:04
#97519 #97519
User since
2006-11-29
340 Artikel
BenutzerIn
[default_avatar]
So, entschuldige das ich jetzt erst poste, ich hatte zwischendurch leider zutun.

Ich habe gerade ein Skript entworfen, das mit den Daten aus dem Link super funktioniert:
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
while ( my $line = <DATA> ) {
chomp($line);
print "Zeile: $line\n";

# Optionen für Zeile2
my %z2opt = ( Authority => 0, Exit => 0, Fast => 0, Guard => 0,
Running => 0, Stable => 0, V2Dir => 0, Valid => 0 );
my $z2optstring = join( '|', keys %z2opt );

# Zeile3
if ( $line =~ /^opt v (\w+) ((?:\d+\.)*?\d+)$/ ) {
print "Zeilentyp: 3\nName: $1\nVersion: $2\n";
}

# Zeile1
if ( $line =~ /\s(\d{4}-\d\d-\d\d)\s(\d\d:\d\d:\d\d)\s(\d+\.\d+\.\d+\.\d+)\s(\d+)\s\d+$/ ) {
print "Zeilentyp: 1\nDatum: $1\nUhrzeit: $2\nIP Adresse: $3\nPort: $4\n";
}

# Zeile2
if ( $line =~ /^s\s((?:(?:$z2optstring)\s*)+)$/ ) {
my $options = $1;
print "Zeilentyp: 2\n";

foreach my $opt ( keys %z2opt ) {
$z2opt{$opt} = 1 if $options =~ /$opt/;
print $opt, ': ', $z2opt{$opt} ? 'yes' : 'no', "\n";
}
}

print "\n";
}

Eine Zeile3-Typ Zeile ist in deinen Daten leider nicht vorhanden, daher konnte ich das Verhalten bei einer solchen Zeile leider nicht testen, aber ich denke es wird alles funktionieren.

Zeile3- und Zeile1-Typ Zeilen werden fast genauso gematcht wie auch vorher.
Zeile2-Typ Zeilen haben einen eigenen Hash für die möglichen Optionen bekommen, dadurch ist es möglich die Optionen anhand des Hashes variabel zu halten.
Die Reihenfolge der Optionen spielt jetzt auch keine Rolle mehr.

Abfragen kann man die einzelnen Optionen nachdem die foreach Schleife durchlaufen ist, sie sind dann entweder gesetzt ( 1 ), oder eben nicht gesetzt ( 0 ).

Leider musste ich das Beispiel klein halten und ein paar Kommentare entfernen/verändern, da das Board wohl immer noch die Zeichengrenze auf 2000 eingestellt hat.

MfG
jogi
 2007-08-06 19:26
#97661 #97661
User since
2007-07-25
55 Artikel
BenutzerIn
[default_avatar]
Hey Danke, deine RegEx funktioniert perfekt. Jetzt fehlt mir aber doch noch der Nickname des Routers.

So sieht mein Versuch aus:

Code: (dl )
r AbbyNormal 1kp4+bE83l+pBSDfBgDHju57NFE 3Job71lL5/qbZMzifsCuQCFgbV8 2007-08-06 10:34:06 72.15.233.132 9001 0


Code (perl): (dl )
1
2
3
4
    # Zeile1
    if ( $line =~ /^r\s([a-zA-Z0-9_])\s[a-zA-Z0-9_\/\+]\s[a-zA-Z0-9_\/\+]\s(\d{4}-\d\d-\d\d)\s(\d\d:\d\d:\d\d)\s(\d+\.\d+\.\d+\.\d+)\s(\d+)\s\d+$/ ) {
        print "Zeilentyp: 1\nDatum: $1\nUhrzeit: $2\nIP Adresse: $3\nPort: $4\n";
    }


Was genau stimmt hier nicht?
PerlProfi
 2007-08-06 20:01
#97664 #97664
User since
2006-11-29
340 Artikel
BenutzerIn
[default_avatar]
Da fehlt jeweils ein + hinter den character classes, und in $1 steht jetzt natürlich der Name des Routers, Uhrzeit usw. rutschen auf. ( $2 - $5 )

Ich würde den regulären Ausdruck allerdings auch noch ein bisschen vereinfachen:
Code: (dl )
/^r\s(\S+)\s\S+\s\S+\s(\d{4}-\d\d-\d\d)\s(\d\d:\d\d:\d\d)\s((?:\d+\.){3}\d+)\s(\d+)\s\d+$/

An der Belegung der Variablen ändert sich nichts:
$1 - Name des Routers
$2 - Datum
$3 - Uhrzeit
$4 - IP Adresse
$5 - Port

MfG
jogi
 2007-08-06 22:33
#97672 #97672
User since
2007-07-25
55 Artikel
BenutzerIn
[default_avatar]
Jap, so gehts. Nur 2 Zeile verstehe ich nicht:

Code (perl): (dl )
$line =~ /^s\s((?:(?:$z2optstring)\s*)+)$/


Diese hier auch nicht:

Code (perl): (dl )
print $opt, ': ', $z2opt{$opt} ? 'yes' : 'no', "\n";


Eine kurze Erklärung wäre nett!

Danke,
jogi
nepos
 2007-08-07 10:14
#97687 #97687
User since
2005-08-17
1420 Artikel
BenutzerIn
[Homepage] [default_avatar]
Code (perl): (dl )
print $opt, ': ', $z2opt{$opt} ? 'yes' : 'no', "\n";


Da kommt ein sogenannter ternärer Operator zum Einsatz: ? :
$z2opt{$opt} wird ausgewertet. Ist der Wert true, wird der Wert yes zurückgegeben, ansonsten ein no.
Linuxer
 2007-08-08 00:33
#97746 #97746
User since
2006-01-27
3891 Artikel
HausmeisterIn

user image
Als Erläuterung zum RegEx:

Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
$line =~
/
^s                              # Buchstabe s am Zeilenanfang
\s                              # gefolgt von einem Whitespacezeichen
(                               # einfangende Klammer; was vom Regex hierin gefunden wird, landet in $1
        (?:                     # gruppierende Klammer; *kein* Einfangen
                (?:             # gruppierende Klammer; *kein* Einfangen
                        $z2optstring                    # Skalar mit den Alternativen
                )               # Ende innere gruppierende Klammer; damit sind die Alternativen unter sich
                \s*             # beliebig viele Whitespaces; keines oder mehrere; {0,}; nach jeder Alternative kann min. 1 Whitespace auftauchen
        )+                      # Ende äußere grupp. Klammer; min. ein Vorkommen, oder mehr; {1,}; mindestens eine Alternativ sollte zu finden sein
)                               # Ende der einfangenden Klammer
$                               # Zeilenende
/x
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!
jogi
 2007-08-11 20:30
#97976 #97976
User since
2007-07-25
55 Artikel
BenutzerIn
[default_avatar]
Danke für die Hilfe bis jetzt.

Habe jetzt ein neues Problem:

Ich möchte

Code: (dl )
#Aug 11 18:23:28.562 [Info] exit circ (length 3, exit WhomtheBelltolls): $E53CF5073BD3C79C9D61628789C1856A62D139F5(open) $5C854C6CE50727F32E51274B1CF4DF9693A206EA(open) $337E599367550A6BF3D9785AAB1FABAFEB1B9B0B(open)

matchen aber ich schaffs nicht bis ans Ende der Zeile.

Mein Versuch:
Code (perl): (dl )
1
2
3
 if ($line =~ /\w+\s\d\d:\d\d:\d\d.\d\d\d\s\[Info\]\sexit\scirc\s\(length\s\d/){
print "ok";
}


Wenn ich nach dem \d ein Komma setze passiert gar nix, d.h. es erscheint nicht das erleichternde ok.

Ich würde den Nicknamne und den letzten Fingerprint benötigen.

Wäre dankbar für jede Hilfe.

Jogi
Daxim
 2007-08-11 21:30
#97980 #97980
User since
2007-08-01
114 Artikel
BenutzerIn
[Homepage]
user image
Der Ausdruck matcht auch jetzt schon nicht, ohne Komma. Du hast nicht geschrieben, was der Nickname ist. Ich gehe davon aus, dass es WhomtheBelltolls ist, positioniert vor der schließenden Klammer. Ich gehe davon aus, dass Fingerprints nach dem $ anfangen und bis zum ( gehen.
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
my ($nickname, $last_fingerprint) = $line =~ /
\A      # anchor at start
\#      # literal number sign
\w{3}   # month
\s
\d\d    # day
\s
\d\d:\d\d:\d\d\.\d{3}   # timestamp
\s
\[\w+\] # log level between brackets
\s
.*?     # log msg
\s
\(      # literal paren open
.*?     # stuff in the parens
\s      # space preceding the nickname
(\w+)   # capture the nickname
\)      # literal paren close
:
\s
\$[0-9A-F]{40}\(\w+\)   # literal $, 40 hex digits, paren open, word, paren close
\s
\$[0-9A-F]{40}\(\w+\)   # again
\s
\$([0-9A-F]{40})\(\w+\) # capture last fingerprint
\z      # anchor at end
/msx;   # PBP
<< |< 1 2 >| >> 18 Einträge, 2 Seiten



View all threads created 2007-08-04 19:41.