2015-02-23 79 views
0

文件1倍的值:解析複雜的兩個文件

.... 
Group 2012_fln 
{ 
    vnum 103 
    Type mixed 
    1 1167 1 2 
    2 7731 1 2 
    3 3561 1 2 
    4 8613 1 3 
} 

Group 7612_edb 
{ 
    vnum 104 
    Type other 
    1 6312 1 90 
    2 5241 5 45 
.... 

文件2倍的值:

.... 
1167 ºÎÈ°Àı´Ş°¿ 
7731 ÀÌÆÄÀÇ 
3561 »¡°£»ö 
.... 

所有值已分隔與標籤。順便說一下,這兩個文件中都有數千個值。

因此,這裏是我的問題:

我需要檢查文件1.值存在與否的文件2. 如果1167或7731或3561或8613的值是不存在的文件2.

我需要在每個組中做到這一點。如果不存在,我需要一個錯誤回聲,就像;在組xxx中,xxx vnum不存在。並繼續結束文件1.

我試圖爆炸,但在文件1中有如此多的語法,如組,{},vnum,類型等。我知道,這是非常複雜的,這就是爲什麼我寫在這裏。

我可以分析我的文件2點的值這樣的:

$line = trim($line); 

$token = explode("\t", $line); 

if ("" == $token[0] or "VNUM" == $token[0]) 
    continue; 

$vnum = $token[0]; 
$entry_name = $token[1]; 

所以,我真的需要一個很大的幫助,我花了我的最後兩天,在這個問題......我希望,我適當解釋。

+1

你只關心與4製表符分隔號線匹配? – wilkesybear 2015-02-23 20:29:05

+0

我只需要在第二個選項卡中獲取數字;如:11671 2,「1167」。 – Liveth 2015-02-23 20:30:32

+0

你可以連續做兩次爆炸。例如:第一個爆炸在''}'上,第二個爆炸在'PHP_EOL'上。現在你已經爲每個組獲得了一個數組。使用'substr()'獲取你想要的所有行,除了前五個之外的所有行,你就完成了。 – 2015-02-23 20:35:44

回答

0

如果你需要的是第二列和格式是所有那些你需要一個值的行相同,加載文件轉換爲使用file_get_contents($file1)的字符串並匹配該模式(4個數字用空格分隔)。

是這樣的:

preg_match_all('/^\s*\d+\s+(\d+)\s+\d+\s+\d+\s*$/m', $data, $matches); 

這將設置$matches像的數組:

Array 
(
    [0] => Array 
     (
      [0] =>  1 1167 1 2 
      [1] =>  2 7731 1 2 
      [2] =>  3 3561 1 2 
      [3] =>  4 8613 1 3 
      [4] =>  1 6312 1 90 
      [5] =>  2 5241 5 45 
     ) 

    [1] => Array 
     (
      [0] => 1167 
      [1] => 7731 
      [2] => 3561 
      [3] => 8613 
      [4] => 6312 
      [5] => 5241 
     ) 

) 

$matches[1]將從第二列中的所有值的數組。您可以對$matches[1]進行foreach循環比較,看看該值是否在第二個文件中。我會建議先加載第二個文件並生成一個索引,以便循環遍歷比賽,你可以檢查是否array_key_exists($value, $file2Index)

實例,每個請求:

<?php 
//read the first file in as a string 
$file1 = file_get_contents("/path/to/file1"); 
//read the second file in as an array 
$file2 = file("/path/to/file2"); 

//index from file2 that we are going to build 
$file2Index = array(); 

foreach($file2 as $line){ 
    //split the line 
    $line = explode("\t", $line, 2); 
    //validate the line, should be only 2 values after explode and first should be a number 
    if(count($line) == 2 && is_numeric($line[0])){ 
     //add to index 
     $file2Index[$line[0]] = $line[1]; 
    } 
} 

//now get all the values from file1 that we want (second column) 
preg_match_all('/^\s*\d+\s*(\d+)\s*\d+\s*\d+\s*$/m', $data, $matches); 

$file1Values = array_unique($matches[1]); 

//loop over the matches from column 2 
foreach($file1Values as $value){ 
    //check if the key doesn't exist 
    if(!isset($file2Index[$value])){ 
     //echo error message 
     echo "Value {$value} does not exist in file2<br>"; 
    } 
} 
+0

你應該在'array_key_exists'上使用'isset'。這是一個(僞)常量操作與線性操作 – wilkesybear 2015-02-23 20:39:59

+0

@wilkesybear,只要您不希望在值爲空時返回假陰性,那麼該操作也可以工作。在這種情況下,您可能會自己構建索引,這可能不是問題。 – 2015-02-23 20:41:29

+0

對,好點。但由於「我們」正在製作數組,我們可以使每個值都成爲「'key'=> true」以確保'isset'的行爲正確。 – wilkesybear 2015-02-23 20:45:03

1

我建議使用正則表達式來解析您的數據,因爲它看起來每行都遵循特定的格式。對於文件1,您可以設置一個表達式,如

^\t(\d+)\t(\d+)\t(\d+)\t(\d+) 

這表示匹配一個製表符,後跟至少一個數字字符,四次。任何匹配的行都將是您關心的行。從那裏,你有興趣在第二組,或$2

對於文件中的兩個,你可能要像

^(\d+).* 

此說,比賽至少一位啓動該行,然後還要別的嗎。所以,你關心的是第一個(也是唯一的)分組,$1

從第一個文件或第二個文件構建一個數字映射,然後遍歷來自另一個文件的匹配並檢查該映射。

由於您使用PHP,你可以使用preg_match爲正則表達式http://php.net/manual/en/function.preg-match.php