2017-02-10 3 views
0

ich versuche, eine iCal zu analysieren:preg_match_all auf Remote-Inhalt

 
    //open file 
    $calendar = file_get_contents('http://app.kigo.net/public/ics.php?c-7ca2eb67c1a7fa8b87b2434ed1096076-422-9871b35967bb29f999cd11ac72943011'); 
    //debug purpose 
    echo $calendar; 
    //parse string 
    preg_match_all('#^BEGIN\:VEVENT.*?END\:VEVENT$#sm',$calendar,$results,PREG_SET_ORDER); 
    //output: empty! 
    print_r($results); 

es gibt ein leeres Array.

Wie auch immer, wenn ich den "$ calendar" Inhalt auf eine andere Variable kopiere/einfüge, und es mit demselben regexp parse, funktioniert es gut.

Warum, wenn ich preg_match_all auf der gleichen Zeichenfolge direkt von file_get_contents aufrufen, funktioniert es falsch?

+0

Gibt die URI eine Datei mit den richtigen Dateiköpfen zurück? Oder sogar Inhalt. Versuchen Sie, den Inhalt auf der Seite zu wiederholen. – Mouser

+0

Zuerst print_r Ihre $ calandar und überprüfen, ob leer oder falsch –

+0

Ich habe etwas wie * Fehler beim Öffnen von Stream: php_network_getaddresses: getaddrinfo fehlgeschlagen * –

Antwort

1

Die Remote-Datei verwendet die Sequenz CR LF als Newline, deshalb stimmt der Anker $ nicht überein. Wenn Sie den Dateiinhalt in eine Anwendung kopieren oder einfügen, die standardmäßig nur LF als Newline verwendet, wird die Sequenz CR LF wahrscheinlich still durch LF ersetzt und Ihr Pattern funktioniert.

Mehrere Möglichkeiten, das Problem zu lösen:

1) schreibt ausdrücklich den Wagenrücklauf in Ihrem Muster:

#^BEGIN:VEVENT.*?END:VEVENT\r$#sm 

Wenn Sie am Ende des Spiels, Gebrauchs nicht den Wagenrücklauf wollen trim oder setzen Sie es in eine Lookahead-Behauptung: #^BEGIN:VEVENT.*?END:VEVENT(?=\r$)#sm. Sie können auch die $ entfernen und den Alias ​​verwenden, der \r, \r\n und \n entspricht.

2) erlauben die $ unabhängig von der Neuzeilensequenz entsprechen bei allen mit der Richtlinie (*ANYCRLF)

#(*ANYCRLF)^BEGIN:VEVENT.*?END:VEVENT$#sm 

3) Sie ein Muster nicht (schließlich verwenden Sie nur für die Blöcke zwischen Festnetz suchen, und wenn die Datei ein bisschen zu lang sein kann, ist es eleganter und spart Speicher Dateien von Zeile zu lesen und einen Generator zu verwenden Blöcke zurückzukehren):

$filePath = 'http://app.kigo.net/public/ics.php?c-7ca2eb67c1a7fa8b87b2434ed1096076-422-9871b35967bb29f999cd11ac72943011'; 

try { 
    if (false === $fp = fopen($filePath, 'rb')) 
     throw new Exception('Could not open the file!'); 

} catch (Exception $e) { 
    echo 'Error (File: ' . $e->getFile() . ', line ' . $e->getLine() . '): ' . $e->getMessage(); 
} 

foreach (genBlocks($fp, "BEGIN:VEVENT\r\n", "END:VEVENT\r\n") as $block) { 
    echo $block . PHP_EOL; 
} 

fclose($fp); 

function genBlocks($fp, $start, $end, $buffer = 1024) { 
    $block = false; 
    while (false !== $line = fgets($fp, $buffer)) { 
     if ($line === $start) { 
      $block = $line; 
     } elseif ($block !== false) { 
      $block .= $line; 
      if ($line === $end) { 
       yield $block; 
       $block = false; 
      } 
     } 
    } 
} 

Hinweis: Sie können al Verwenden Sie also stream_get_line anstelle von fgets, da dieser eine Zeile ohne die Newline-Sequenz zurückgeben kann.

+0

Mit der zweiten Lösung (* ANYCRLF) löste ich alle Probleme! Vielen Dank wirklich! – Infocurci