2010-03-22 18 views
0

好的,所以我試着先搜索一下,但我並不完全知道如何說出這個問題或搜索短語。讓我解釋。如何在PHP中首先處理最大的匹配項?

我有一個看起來像這樣的數據:

<!-- data:start --> 
    <!-- 0:start --> 
     <!-- 0:start -->0,9<!-- 0:stop --> 
     <!-- 1:start -->0,0<!-- 1:stop --> 
     <!-- 2:start -->9,0<!-- 2:stop --> 
     <!-- 3:start -->9,9<!-- 3:stop --> 
     <!-- 4:start -->0,9<!-- 4:stop --> 
    <!-- 0:stop --> 
    <!-- 1:start --> 
     <!-- 0:start -->1,5<!-- 0:stop --> 
     <!-- 1:start -->1,6<!-- 1:stop --> 
     <!-- 2:start -->3,6<!-- 2:stop --> 
     <!-- 3:start -->3,8<!-- 3:stop --> 
     <!-- 4:start -->4,8<!-- 4:stop --> 
    <!-- 1:stop --> 
    <!-- 2:start --> 
     <!-- 0:start -->0,7<!-- 0:stop --> 
     <!-- 1:start -->1,7<!-- 1:stop --> 
    <!-- 2:stop --> 
<!-- data:stop --> 

所以它基本上是一幫點。這是我目前使用嘗試和解析它,這樣它會創建這樣一個數組代碼:

Array (
    0 => Array (
     0 => "0,9", 
     1 => "0,0", 
     2 => "9,0", 
     3 => "9,9", 
     4 => "0,9" 
    ), 
    1 => Array (
     0 => "1,5", 
     1 => "1,6", 
     2 => "3,6", 
     3 => "3,8", 
     4 => "4,8" 
    ), 
    2 => Array (
     0 => "0,7", 
     1 => "1,7" 
    ) 
) 

但是,它返回一個數組,看起來像這樣:

Array (
    0 => "0,9", 
    1 => "0,0", 
    2 => "9,0" 
) 

查看我屏幕上的較大數組,您會發現它在匹配時設置該變量的第一個實例。那麼,如何才能找到最廣泛的匹配,然後處理內部。這是我目前使用的功能:

function explosion($text) { 
    $number = preg_match_all("/(<!-- ([\w]+):start -->)\n?(.*?)\n?(<!-- \\2:stop -->)/s", $text, $matches, PREG_SET_ORDER); 
    if ($number == 0) return $text; 
    else unset($item); 
    foreach ($matches as $item) if (empty($data[$item[2]])) $data[$item[2]] = $this->explosion($item[3]); 
    return $data; 
} 

我敢肯定,這將是愚蠢的東西,簡單的,我已經被忽視,但只是使這一個簡單的答案給你,我想。

編輯:這是我從這個樣本的整個數據集的full output log。這些標籤被打印出來(用>和<代替),它們都在一個巨大的<code></code>元素中,以便於閱讀。

這裏是一個真實搞亂了一部分:

Array ([0] => <!-- 0:start --> <!-- 0:start -->0,9<!-- 0:stop --> [1] => 0 [2] => <!-- 0:start -->0,9) 

0 => <!-- 0:start -->0,9 

因此它停在停止標籤中第一次出現了另一塊這裏面。我是否應該思考相反的方向並首先處理最小的碎片,替換那些碎片以便不會中斷較大的碎片,然後處理較大的碎片?

+3

爲什麼不使用JSON而不是這種奇怪的格式? – kennytm 2010-03-22 07:46:15

回答

2

在這裏你去:

function explosion($text) { 
    preg_match_all("/<!-- ([\d]+):start -->(.+?)<!-- .*:stop -->/", $text, $matches, PREG_SET_ORDER); 

    $return = array(); 
    foreach($matches as $match) { 
     if($match[1]==0) { 
      $return[] = array(); 
     } 
     $return[count($return)-1][] = $match[2]; 
    } 
    return $return; 
} 
+0

+1這對我也適用。 – pinaki 2010-03-22 10:09:40

+0

我不明白這是如何在一個更大的模型中工作?如果它匹配標籤中的0,那麼這隻會捕獲數組嗎?我在問題中添加了一個日誌,可能會有所幫助。 – animuson 2010-03-22 18:26:46

+0

這個想法是,你不打擾匹配外部標籤,只是內部的標籤。只要開始標籤中的數字是'0',就知道外部標籤必須已經更改,因此您可以爲下一批結果創建另一個數組。 – 2010-03-22 20:40:49

1

嗯,這對我的作品:

function explosion($text) { 
    $number = preg_match_all('/<(.*?)>(.+?)[<]/s', $text, $matches); 
    if ($number == 0) return $text; 

    $temp = array(); 
    $data = array(); 
    foreach($matches[2] as $coords){ 
     if(trim($coords)==""){ 
      if(!empty($temp)){ 
       $data[] = $temp; 
       $temp = array(); 
      } 
     }else{ 
      $temp[] = $coords; 
     } 
    } 
    return $data; 
} 

與您的代碼的問題是,它拿起子標記和標記值。當然,它在瀏覽器中打印時會隱藏,因此請嘗試記錄它以進行調試。

相關問題