regEx Pattern

Tach Community,

was mir stets ein raetsel bleibt… Regulaere Ausdruecke.
Waere jemand so freundlich und koennte mir ein Pattern fuer folgende anforderung liefern ----->

Ein LOGfile wird Zeilenweise ausgelesen. Die Zeilen liegen in einem Array.

Dummerweise kann ich das LogFile nicht beeinflussen. Es gibt keine Spaltentrenner (tabs,kommata, oder dergleichen)… allerdings kann man ein muster erkennen.

ich brauche jetzt patterns die folgende muster erkennen und in einen array schreiben:

20.06.2007, 13:21:40: SYSTEM: Datei gelöscht
20.06.2007, 13:22:33: SYSTEM: Monitoring start
20.06.2007, 13:25:21: EVENT: Undefiniert
20.06.2007, 13:25:25: EVENT: Undefiniert

soll in einen array (erste zeile des logs als beispiel)

$logFile1 = array(
// 20.06.07 13:21:40,SYSTEM,Datei gelöscht 
 $datum =\> array($zeit,$platform,$logStr)
)

nach SYSTEM folgt immer ein „:“ und nach der Uhrzeit auch.

bei mir matched das einfach nicht.

herzlichen Dank und Grusz
vom

PixelKoenig

ich brauche jetzt patterns die folgende muster erkennen und in
einen array schreiben:

20.06.2007, 13:21:40: SYSTEM: Datei gelöscht
20.06.2007, 13:22:33: SYSTEM: Monitoring start
20.06.2007, 13:25:21: EVENT: Undefiniert
20.06.2007, 13:25:25: EVENT: Undefiniert

soll in einen array (erste zeile des logs als beispiel)

$logFile1 = array(
// 20.06.07 13:21:40,SYSTEM,Datei gelöscht
$datum => array($zeit,$platform,$logStr)
)

nach SYSTEM folgt immer ein „:“ und nach der Uhrzeit auch.

bei mir matched das einfach nicht.

ereg('^(.+): (.+): (.+)$',"20.06.2007, 13:21:40: SYSTEM: Datei gelöscht",$matches);
print\_r($matches);

ereg(’^(.+): (.+): (.+)$’,„20.06.2007, 13:21:40: SYSTEM: Datei
gelöscht“,$matches);
print_r($matches);

was soll ich sagen…
das matched dann wohl…

-)

danke schoen

Grusz

PixelKoenig

Hallo Pixelkönig,

20.06.2007, 13:25:25: EVENT: Undefiniert

da tut es auch ein „$array = array_map(„trim“, explode(“:", $string));", wenn „nur“ am : trennen willst und die Leerzeichen dazwischen entfernen, sollte ggfs. schneller sein als ein RegEx.

Alexander

Hi Alexander,

20.06.2007, 13:25:25: EVENT: Undefiniert

da tut es auch ein „$array = array_map(„trim“, explode(“:",
$string));", wenn „nur“ am : trennen willst und die
Leerzeichen dazwischen entfernen, sollte ggfs. schneller sein
als ein RegEx.

nee. das beispiel von dog war schon perfekt.
die trennung nach „:“ wuerde ja nur die uhrzeit
zerschneiden und nochmal nach dem event.
das ist aber nicht gewuenscht … :smile:

trotzdem danke

grusz

PixelKoenig

20.06.2007, 13:25:25: EVENT: Undefiniert

da tut es auch ein „$array = array_map(„trim“, explode(“:",
$string));", wenn „nur“ am : trennen willst und die
Leerzeichen dazwischen entfernen, sollte ggfs. schneller sein
als ein RegEx.

nee. das beispiel von dog war schon perfekt.
die trennung nach „:“ wuerde ja nur die uhrzeit
zerschneiden und nochmal nach dem event.

du sollst ja auch den explode auf doppelpunktleerzeichen machen :smile:

du sollst ja auch den explode auf doppelpunktleerzeichen
machen :smile:

ups ueberlesen…
dennoch ist deine variante fuer mich sinnvoller, weil im letzten teil… kann es zu usereingaben kommen. und wenn da einer schreibt „Montag: nix gemacht“ gibts da n problem :smile:

grusz

PixelKoenig

Du kannst bei dem Explode auch nen Limit angeben wodurch auch userabfragen abgefangen werden könnten.

Gruß
Phillip

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Hallo,

ereg(’^(.+): (.+): (.+)$’,„20.06.2007, 13:21:40: SYSTEM: Datei
gelöscht“,$matches);
print_r($matches);

Das ist schon richtig und auch schön, aber hier könnte man
die Regel anwenden: ‚if you know the delimiter, use split‘
(wie es hier bereits erwähnt wurde).

Da es sich um eine „Verwandlung“ eines Arrays in ein
neues Array handelt, könnte man bei dieser Gelegenheit
auch gleich eine map-Funktion anbringen, also etwa
so (Beispiel):

 $org\_lines = array(
 '20.06.2007, 13:21:40: SYSTEM: Datei gelöscht',
 '20.06.2007, 13:22:33: SYSTEM: Monitoring start',
 '20.06.2007, 13:25:21: EVENT: Undefiniert',
 '20.06.2007, 13:25:25: EVENT: Undefiniert' );
 
 function splitme ($elm) { return preg\_split('/:\s+/', $elm); }
 
 $spl\_lines = array\_map( splitme, $org\_lines );
 
 print\_r($spl\_lines);

Grüße

CMБ

Hallo,

ups ueberlesen…
dennoch ist deine variante fuer mich sinnvoller, weil im
letzten teil… kann es zu usereingaben kommen. und wenn da
einer schreibt „Montag: nix gemacht“ gibts da n problem :smile:

Ich hab mal an einer Variante mit split (wie explode)
gebastelt, die müsste sogar mit diesen Problemfällen
gehen. Es wird eine Schranke für split verwendet, wie
im nebenstehenden Posting vorgeschlagen …

 $org\_lines = array(
 '20.06.2007, 13:21:40: SYSTEM: Datei gelöscht Montag: nix problem',
 '20.06.2007, 13:22:33: SYSTEM: Monitoring start',
 '20.06.2007, 13:25:21: EVENT: Undefiniert',
 '20.06.2007, 13:25:25: EVENT: Undefiniert' );
 
 $result = array();
 
 foreach( $org\_lines as $line ) 
 if( $s = preg\_split( '/[:,]\s+/', $line, 4 ) ) {
 array\_key\_exists( $s[0], $result ) || $result[$s[0] ] = array();
 array\_push( $result[$s[0] ], array\_slice($s, 1) );
 }
 
 print\_r($result);

Grüße

CMБ

PS.: an die Freaks – nimmt man heute eher „explode“
oder eher „preg_split“ und warum bzw. wo?

Hallo,

PS.: an die Freaks – nimmt man heute eher „explode“
oder eher „preg_split“ und warum bzw. wo?

Explode ist deutlich schneller solange keine Regulären Ausdrücke genutzt werden.

Gruß
Phillip

Hallo,

ups ueberlesen…
dennoch ist deine variante fuer mich sinnvoller, weil im
letzten teil… kann es zu usereingaben kommen. und wenn da
einer schreibt „Montag: nix gemacht“ gibts da n problem :smile:

Ich hab mal an einer Variante mit split (wie explode)
gebastelt, die müsste sogar mit diesen Problemfällen
gehen. Es wird eine Schranke für split verwendet, wie
im nebenstehenden Posting vorgeschlagen …

$org_lines =
array(
‚20.06.2007, 13:21:40: SYSTEM: Datei gelöscht Montag: nix
problem‘,
‚20.06.2007, 13:22:33: SYSTEM: Monitoring start‘,
‚20.06.2007, 13:25:21: EVENT: Undefiniert‘,
‚20.06.2007, 13:25:25: EVENT: Undefiniert‘ );

$result = array();

foreach( $org_lines as $line )
if( $s = preg_split( ‚/[:,]\s+/‘, $line, 4 ) ) {
array_key_exists( $s[0], $result ) || $result[$s[0] ]
= array();
array_push( $result[$s[0] ], array_slice($s, 1) );
}

print_r($result);

siehst du, perl ist doch unleserlich
das ganze nochmal nach KISS

siehst du, perl ist doch unleserlich.

das ganze nochmal nach KISS

$result = array();
foreach( $org\_lines as $line )
 {
 $felder = explode(": ",$line);
 $timest = array\_shift($felder);
 $system = array\_shift($felder);
 $msg = implode(": ",$felder);

 $result[] = array($timest,$system,$msg);
 }

Hallo,

siehst du, perl ist doch unleserlich.
das ganze nochmal nach KISS

keep it simple & stupid

(we’ll see)

$result = array();
foreach( $org_lines as $line )
{
$felder = explode(": „,$line);
$timest = array_shift($felder);
$system = array_shift($felder);
$msg = implode(“: ",$felder);

$result[] = array($timest,$system,$msg);
}

Das Problem an Deiner Variante ist wahrscheinlich,
dass sie etwas ganz anderes tut als die Meinige.

IMHO wollte der OP ein assoziatives Array haben,
welches als ‚literalen‘ Feldindex das Datum, also
die Zeichen bis zum ersten Komma, verwendet und
als Inhalt dieses Feldelementes ein Array mit
den assoziierten „Daten“-Einträgen bereitstellt.

Ich kann nicht erkennen, wo Dein Quelltext (der IMHO
viel zu „wortreich“ ausgefallen ist :wink:, dies tut.

Daher will ich, um die Idee zu unterstreichen,
die entsprechende Schleife nochmal mit den
zugehörigen Kommentaren posten.

 ...
 foreach( $org\_lines as $line ) 
 if( $s = preg\_split( '/[:,]\s+/', $line, 4 ) ) {
 # wenn split klappte, benutze s[0] (Datum) als Feldindex für
 # result[], pruefe aber, ob Feldindex schon existiert (|| 'Perl Idiom')
 array\_key\_exists( $s[0], $result ) || $result[$s[0] ] = array();
 # lege das restliche Array s[1 .. N-1] (slice ohne s[0]) bei 
 # diesem Feldelement (result[]) ab
 array\_push( $result[$s[0] ], array\_slice($s, 1) );
 }
 ...

Mich würde aber trotzdem interessieren, ob es eine
„bessere“, also kompaktere (OK, es sind nur 2 Zeilen nach
dem split) und dennoch „lesbare“ Lösung gäbe. Mir ist auch
bei längerem Draufschauen Keine andere eingefallen :wink:

Grüße

CMБ

siehst du, perl ist doch unleserlich.
das ganze nochmal nach KISS

keep it simple & stupid

(we’ll see)

Das Problem an Deiner Variante ist wahrscheinlich,
dass sie etwas ganz anderes tut als die Meinige.

da hast du recht, habe gerade nochmal oben geschaut, er schrieb:

$logFile1 = array(
// 20.06.07 13:21:40,SYSTEM,Datei gelöscht
$datum => array($zeit,$platform,$logStr)
)

dann macht dein ansatz auch gleich mehr sinn :smile:

IMHO wollte der OP ein assoziatives Array haben,
welches als ‚literalen‘ Feldindex das Datum, also

if( $s = preg_split( ‚/[:,]\s+/‘, $line, 4 ) )

das if an der stelle ist fuer umsonst, weil preg_split immer ein array zurueckgibt siehe unten

Mich würde aber trotzdem interessieren, ob es eine
„bessere“, also kompaktere (OK, es sind nur 2 Zeilen nach
dem split) und dennoch „lesbare“ Lösung gäbe. Mir ist auch
bei längerem Draufschauen Keine andere eingefallen :wink:

was haelst du von der variante:

$result = array();
foreach( $org\_lines as $line )
 {
 $felder = preg\_split( '/[:,]\s+/', $line, 4 ); 
 $datum = array\_shift($felder);

 if ( ! isset($result[$datum]) )
 { $result[$datum] = array(); }

 $result[$datum][] = $felder;

 }

wenn man notices abschaltet kann man das weniger wortreich formulieren:

$result = array();
foreach( $org\_lines as $line )
 {
 $felder = preg\_split( '/[:,]\s+/', $line, 4 );
 $result[array\_shift($felder)][] = $felder;
 }

das einzige problem, das ich mit dem preg_split habe ist, dass es die eingangsdaten nicht validiert, weil es auch bei dem folgenden input ungeruehrt weitermacht:

$org_lines = explode("\n",„20.06.2007, 13:21:40: SYSTEM: Datei gelöscht
20.06.2007, 13:22:33: SYSTEM: Monitoring start
21.06.2007, 13:25:21: EVENT: Undefiniert
shit happens
21.06.2007, 13:25:25: EVENT: Undefiniert“);