将不规则的CSV数据提取到结构化数组中 - 尝试使用PHP

时间:2012-05-15 22:30:20

标签: php arrays csv

使用PHP尝试解决此问题,但对其他解决方案(Python,Bash等)开放。

我有以下格式的csv数据: 注意:商店名称ID(第1行和第6行)始终为10位数 产品ID(col1,行2,3,4和7,8,9,10,11)始终为7位数。

Store name 0123456789,,,
0123456,product desc,1,1.00
1234567,product desc2,1,2.00
2345678,product desc3,1,3.00
Ship Total,6.00,,
Store name2 9876543210,,,
0123456,product desc,4,1.00
1234567,product desc2,2,2.00
2345678,product desc3,1,3.00
3456789,product desc4,3,4.00
45678901,product desc5,1,5.00
Ship Total,28.00,,

所需格式为:

0123456789,0123456,product desc,1,1.00
0123456789,1234567,product desc2,1,2.00
0123456789,2345678,product desc3,1,3.00
9876543210,0123456,product desc,4,1.00
9876543210,1234567,product desc2,2,2.00
9876543210,2345678,product desc3,1,3.00
9876543210,3456789,product desc4,3,4.00
9876543210,45678901,product desc5,1,5.00

我有一个以上述格式解析数据的程序。

我已经将商店放入一个数组,并将交易转换为另一个数组......只需将它们放在一起。

这是我到目前为止所得到的。

$csv = array();
$file = fopen($datafile, 'r');

while (($result = fgetcsv($file)) !== false)
{
    $csv[] = $result;
}

fclose($file);

foreach ($csv as $key => $value) { 
    if (preg_match('/\d{10}$/', $value[0],$store)) {
        $stores[$key] .= $store[0];
    }
}
print_r($stores);

foreach ($csv as $key => $value) {
    if (preg_match('/^\d{7}/', $value[0],$transaction)) {
        $transactions[$key] = array("Item"=>$value[0],"Desc"=>$value[1],"Qty"=>$value[2],"Price"=>$value[3]);
    }
}
print_r($transactions)

print_r结果:

$csv = array();
$file = fopen($datafile, 'r');

while (($result = fgetcsv($file)) !== false)
{
    $csv[] = $result;
}

fclose($file);

foreach ($csv as $key => $value) { 
    if (preg_match('/\d{10}$/', $value[0],$store)) {
        $stores[$key] .= $store[0];
    }
}
print_r($stores);

foreach ($csv as $key => $value) {
    if (preg_match('/^\d{7}/', $value[0],$transaction)) {
        $transactions[$key] = array("Item"=>$value[0],"Desc"=>$value[1],"Qty"=>$value[2],"Price"=>$value[3]);
    }
}
print_r($transactions)

回答后编辑。这是完美的。

[代码]

Array
(
    [0] => 0123456789
    [5] => 9876543210
)

Array
(
    [1] => Array
        (
            [Item] => 0123456
            [Desc] => product desc
            [Qty] => 1
            [Price] => 1.00
        )
...
... arrays 2,3,4,6,7,8,9....
...

    [10] => Array
        (
            [Item] => 45678901
            [Desc] => product desc5
            [Qty] => 1
            [Price] => 5.00
        )
)

[/代码]

2 个答案:

答案 0 :(得分:0)

$file = fopen($datafile, 'r'); 

$Out = '';
$LastStore = '';
while (($result = fgetcsv($file)) !== false) 
{ 
    if (preg_match('/\d{10}$/', $result[0],$store)) { 
        $LastStore = $store;
    } elseif (preg_match('/^\d{7}/', $result[0],$transaction)) { {
        $aT = array("Store"=>$LastStore, "Item"=>$transaction[0],"Desc"=>$transaction[1],"Qty"=>$transaction[2],"Price"=>$transaction[3])
        $Out .= implode(',', $aT) . "\n";

    }
} 
fclose($file); 

// Output as file (if this is as intended). Otherwise you have $Out to be the CSV string you need.    
file_put_contents($OutFileName, $Out);

或者,如果你想要一个大数组中的所有东西

$file = fopen($datafile, 'r'); 

$aT = array();
$LastStore = '';
while (($result = fgetcsv($file)) !== false) 
{ 
    if (preg_match('/\d{10}$/', $result[0],$store)) { 
        $LastStore = $store;
    } elseif (preg_match('/^\d{7}/', $result[0],$transaction)) { {
        $aT[] = array("Store"=>$LastStore, "Item"=>$transaction[0],"Desc"=>$transaction[1],"Qty"=>$transaction[2],"Price"=>$transaction[3])
    }
} 
fclose($file); 

答案 1 :(得分:0)

我会建议这样的事情

$handle = @fopen($datafile, "r");
if ($handle) {
    $Out = '';
    $Store = '';
    while (($buffer = fgets($handle)) !== false) {
        if (substr($buffer, 0, 5) == 'Store') {
            preg_match('/\d{10}/', $buffer, $storeId);
            $Store = $storeId[0] . ',';
        } else if (substr($buffer, 0, 4) == 'Ship') {
            // ignore
        } else {
            $Out .= $Store . $buffer . "\n";
        }
    }
}
fclose($handle);

file_put_contents('Results.txt', $Out);