2011-07-17 141 views
4

第一個字我有一個看起來像這樣(用換行和怪異的間距)的文件:PHP抓住從線

Player:   Alive: Score: Ping: Member of Team: 
player1   No  16  69 dogs  
bug    Yes 2  63 insects    
name with space No  0  69 cats   
bob    No  0  69 dogs 

我怎麼能搶了先列,把它變成一個數組?

所需的輸出
$玩家[1] ----> 「PLAYER1」
$玩家[2] ----> 「錯誤」
$玩家[3] ---- > 「的名字與空間」
$球員[4] ----> 「鮑勃」

+1

他們是列製表符分隔還是所有空格? – Gordon

回答

1

這裏是一個迭代的方法:

class SubstringIterator extends IteratorIterator 
{ 
    protected $startAtOffset, $endAtOffset; 

    public function __construct($iterator, $startAtOffset, $endAtOffset = null) { 
     parent::__construct($iterator); 
     $this->startAtOffset = $startAtOffset; 
     $this->endAtOffset = $endAtOffset; 
    } 

    public function current() { 
     return substr(parent::current(), $this->startAtOffset, $this->endAtOffset); 
    } 
} 

你會使用這樣的:

$playerIterator = new LimitIterator(
    new SubstringIterator(
     new SplFileObject('yourFile.txt'), 
     0, // start at beginning of line 
     15 // end before Alive: 
    ) 
    , 1 // start at line 2 in file (omits the headline) 
); 

然後,您可以foreach在迭代器,例如

foreach ($playerIterator as $player) { 
    echo $player, PHP_EOL; 
} 

輸出:

player1   
bug    
name with space 
bob   

或轉換堆疊迭代到一個數組:

$array = iterator_to_array($playerIterator); 
print_r($array); 

輸出:

Array 
(
    [1] => player1   
    [2] => bug    
    [3] => name with space 
    [4] => bob    
) 

Demo of above examples with your file's data

+0

謝謝,你的工作很完美 – dukevin

6
<?php 
    $a=file('file.txt'); 
    $pos=strpos($a[0],'Alive:'); 
    $res=array_map(function($x) use ($pos){ 
     return trim(substr($x,0,$pos)); 
    },$a); 
    unset($res[0]); 

對於PHP 5.2-

<?php 
    $a=file('file.txt'); 
    $pos=strpos($a[0],'Alive:'); 
    function funcname($x,$pos){ 
     return trim(substr($x,0,$pos)); 
    } 
    $res=array_map('funcname',$a,array_fill(0,count($a),$pos)); 
    unset($res[0]); 
+0

使用'unset'離開從索引1開始的數組。'array_shift()'更好。 :) – Tomalak

+1

@Tomalak:嘗試再次檢查「Desired Output:」;) – RiaD

+0

@Tomalak:在我看來,這是OPs數組從1開始的預期行爲。 – Nobody

0

最簡單的方法:

$file = file_get_contents($filepath); 
$column_width = strpos($file,'Alive:') + 1; 
preg_match_all('/^(.{'.$column_width.'}).*$/m', $file, $matches); 
unset($matches[1][0]); 
$result = array_map('trim', $matches[1]); 

最後$結果是:

array (
    0 => 'player1', 
    1 => 'bug', 
    2 => 'name with space', 
    3 => 'bob', 
), 
+0

這個應用於第一個數據行字符串的正則表達式導致只包含「n」的數組。看起來漂亮,雖然 – Raffael

+0

固定,我的錯。 – WASD42

+0

這不是OP的預期結果。再看看帖子。 – Raffael

3

使用正則表達式可能看起來像另一種選擇:

preg_match_all('/^.{0,15}?(?= {2}|(?<=^.{15}))/m', $subject, $matches); 
$players = $matches[0]; 
unset($players[0]); // remove header 

var_export($players); 

所得$players陣列看起來像

array (
    1 => 'player1', 
    2 => 'bug', 
    3 => 'name with space', 
    4 => 'bob', 
) 

注意:正如任何基於正則表達式的解決方案,如果上面看起來像魔術那麼請不要使用它。如果你不知道它實際上試圖匹配什麼,那麼在你的代碼中複製和粘貼一個正則表達式是絕對沒有意義的。

+0

如果玩家姓名的最大長度超過15個字符,會發生什麼情況? :) – WASD42

+1

上面的答案只處理問題中給出的示例文件。如果OP想要處理其他輸入,請在問題中詳細說明,以便回答者知道要處理的限制和範圍。附:修改長度檢查是一個微不足道的方法。 – salathe

+0

比我的答案是相同的,但我的-1票;)順便說一句你用什麼目的斷言?事實上,腳本唯一需要做的就是從每一行中獲取前N個字符:)然後,正則表達式應該只是'/ ^(。{15})。* $/m',其中15是最大列寬度:] – WASD42