Problem mit preg_match

Sven4972

Mitglied
Hallo,

ich habe eine Textdatei die folgendermaßen ausschaut:

Code:
##ID:08.12.28.18.45.14
##DET:lotm;24
##SP1:Robo;-40
##SP2:Rheinpirat;-14
##SP3:gentzy;36
##SP4:lotm;18

Diese Textdatei soll in die einzelnen Bestandteile zerlegt werden,
dazu habe ich den Befehl preg_match gefunden.

Nun komme ich aber nicht weiter, hier der Code den ich bisher habe:

PHP:
$datei = fopen("text.txt", "r");
   
  // erste Zeile einlesen
  if (!$line = fgets($datei)) {
    die('Lesen gescheitert!');
  }

  $pcre = '/##ID:[0-9]{1,2}.[0-9]{1,2}.[0-9]{1,2}.[0-9]{1,2}.[0-9]{1,2}.[0-9]{1,2}/';
  
  if (!preg_match($pcre, $line, $hits)) {
  die('Zeile hat falsches Format!');
  }

Das funktioniert auch und die Zeile wird geteilt.

Jetzt möchte ich das bei den anderen Zeilen ebenfalls machen,
aber ich weiß nicht wie dann folgende Codestelle auszusehen hat:

PHP:
$pcre = '/##ID:[0-9]{1,2}.[0-9]{1,2}.[0-9]{1,2}.[0-9]{1,2}.[0-9]{1,2}.[0-9]{1,2}/';

Mir wird immer angezeigt, das die Zeile ein falsches Format besitzt.
Die Zeilen können auch immer eine andere Länge haben.

Und kann ich mir die einzelnen Bestandteile, der Zeilen dann per echo ausgeben lassen?


LG Sven
 
Hi Sven!

Dass Du bei der zweiten Zeile gemeldet bekommst, kommt daher, dass preg_match nach der ersten Zeile aufhört zu matchen. Du prüfst in

PHP:
if (!preg_match($pcre, $line, $hits)) {
     die('Zeile hat falsches Format!');
}
auch wie oft die regex gefunden wurde.

Stattdessen solltest du entweder preg_match_all() oder einen foreach-loop über alle Zeilen laufen lassen.


Die Einzelnen Bestandteile kannst Du mit "backreferences" rausziehen. Dazu musst Du die einzelnen Bestandteile die Du haben möchtest mit Klammern versehen. Etwa so:

PHP:
$pcre = '/##ID:([0-9]{1,2}).([0-9]{1,2}).([0-9]{1,2}).([0-9]{1,2}).([0-9]{1,2}).([0-9]{1,2})/';

Ansprechen kannst Du sie dann (in Deinem Fall) mittels der Variablen $hits[1], $hits[2] usw.


Ganz allgemein mal gesagt: :rtfm: ;-) Im PHP-Manual ist das wirklich gut beschrieben - auch auf deutsch...

Ach noch ein kleiner Tipp: Deine Regex geht auch etwas einfacher/besser ;-) --> AddedBytes.com Regex Cheat Sheet

Du könntest beispielsweise das [0-9] mit \d für "digit" ersetzen...
 
Moin Sven :-)

Allgemein wäre erstmal die Frage, in welche Bestandteile du zerlegen willst, ich würde mal tippen, du benötigst 2-3 Bestandteile.

Folgendes würde dir das Ganze in einem Rutsch darin zerlegen(die Schleife zum Durchgehen der Zeilen ist dabei nicht vonnöten):

Code:
$pattern='@^##([A-Z][A-Z\d]+):([^;\r\n]+);?(.*)$@m';

preg_match_all($pattern, file_get_contents('text.txt'),$matches,PREG_SET_ORDER);

echo '<pre>'.print_r($matches,1).'</pre>';

Du erhältst als Teile
  1. die ID(oder wie du das nennen magst zwischen ## und : )
  2. das was zwischen dem Doppelpunkt und dem (optionalen) Semikolon steht
  3. (optional) das, was nach dem Semikolon steht
 
Hallo Sven,

das schaut schon mal gut aus.
Ich müsste die erste Zeile aber auch noch auseinander bekommen.

Code:
##ID:08.12.28.21.27.12

Müsste zu 2008-12-28 und 212712 werden.

Wie kann man das denn machen,
und wie kann ich die ausgegebenen Daten in Variablen bekommen,
so das ich diese weiterverarbeiten kann?


LG Sven
 
hmm, schade dass du meinen Post nicht gelesen hast (und auch das PHP-Manueal), da steht das.

Naja, dann mal Svens code bisserl abgeändert:
PHP:
$pattern = '(\d\d)';
preg_match_all($pattern, '##ID:08.12.28.21.27.12',$matches,PREG_SET_ORDER);
echo '<pre>'.print_r($matches,1).'</pre>';

$date;
$time;

for($i = 0; $i <= 2; $i++)
{
      $date .= $matches[$i][0];
}

for($i = 4; $i <= 5; $i++)
{
      $time .= $matches[$i][0];
}

Das Ganze geht sicher eleganter, aber ich denke, Du verstehst.
 
Zuletzt bearbeitet:
Zurück