2017-02-10 34 views
0

我試圖解析的iCal:preg_match_all對遠程內容

 
    //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); 

它返回一個空數組。無論如何,如果我將「$ calendar」內容複製/粘貼到另一個變量上,並使用相同的正則表達式解析它,它可以正常工作。

爲什麼當我直接從file_get_contents調用相同字符串上的preg_match_all時,它的工作原理錯誤?

+0

uri是否以正確的文件頭返回文件?甚至內容。嘗試將內容回顯到頁面中。 – Mouser

+0

首先print_r你的$ calandar並檢查是否爲空 –

+0

我得到了類似的東西*未能打開流:php_network_getaddresses:getaddrinfo失敗* –

回答

1

遠程文件使用序列CR LF作爲換行符,這就是定位符$不匹配的原因。當您將文件內容複製/粘貼到默認僅使用LF作爲換行符的應用程序中時,序列CR LF可能會以靜默方式替換爲LF,並且您的模式可以工作。

幾種方法來解決這個問題:

1)明確地寫在你的模式回車:

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

如果你不想在比賽中,使用結束回車trim或將其放在前瞻斷言:#^BEGIN:VEVENT.*?END:VEVENT(?=\r$)#sm。 您也可以刪除$並使用與\r\r\n\n匹配的\R別名。

2)允許使用$指令(*ANYCRLF)

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

3)不要使用在所有模式(畢竟你只是在尋找固定線路之間的塊匹配任何新行序列,如果你的文件可能是有點長,它更優雅和節省內存按行讀入文件,並使用一臺發電機返回塊)

$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; 
      } 
     } 
    } 
} 

注意:您可以人所以使用stream_get_line而不是fgets,因爲這一個能夠返回一個沒有換行符序列的行。

+0

第二種解決方案(* ANYCRLF)解決了所有問題!非常感謝! – Infocurci