处理奇怪格式的csv文件

Posted

技术标签:

【中文标题】处理奇怪格式的csv文件【英文标题】:Dealing with a csv file in a strange format 【发布时间】:2020-07-06 23:42:43 【问题描述】:

我正在使用 phpmyadmin 的“加载数据”功能通过上传 csv 文件来更新(或更新)我的数据库中的一些数据。 csv 文件有 50 列和 200k 行。这很好用,并且使用这种格式非常快:

100;101;102;103;104;....
Alfred;Mueller;Exampplestreet 1;12121;Chicago;....
John;Wiliams;Exampplestreet 2;12345;Dallas;....
Mandy;Peterson;Exampplestreet 3;44554;LA;....
...

现在我有机会通过接收数据提供者的 csv 数据文件来完全自动化这个过程。但是数据提供者提供了一个这样的 csv 文件:

100#Alfred;101#Mueller;102#Exampplestreet 1;103#12121;104#Chicago;....
100#John;101#Wiliams;102#Exampplestreet 2;103#12345;104#Dallas;....
100#Mandy;101#Peterson;102#Exampplestreet 3;103#44554;104#LA;....

有没有机会处理提供者的格式?我从来没有使用过像这样格式化的 csv 文件?

【问题讨论】:

【参考方案1】:

看起来您需要从每个值中提取字段类型,不确定这是否相关,但我已将其转换为字段的键,以备不时之需(这不是很大的区别无论如何)。

基本上将每一行读取为 CSV 行(由 ; 分隔),然后将每个字段 explode() 读取为 #,如果有 2 个字段,则将其添加到输出数组 ($data)。 ..

$fileName = "data.csv";
$handle = fopen ( $fileName, "r" );

while ( !feof($handle) )    
    $fileData = fgetcsv( $handle, null, ";" );
    $data = [];
    foreach ( $fileData as $value ) 
        $values = explode("#", $value, 2);
        if ( count($values) == 2 )  
            $data[ $values[0] ] = $values[1];
        
    

    print_r($data);

fclose($handle);

输出将类似于...

Array
(
    [100] => Alfred
    [101] => Mueller
    [102] => Exampplestreet 1
    [103] => 12121
    [104] => Chicago
)

如果您不需要字段类型并且它始终是三个字符后跟一个#,您可以通过更新读取数组的值来缩短它,使用substr() 始终删除前 4 个字符..

while ( !feof($handle) )    
    $data = fgetcsv( $handle, null, ";" );
    foreach ( $data as &$value ) 
        $value = substr($value, 4);
    

    print_r($data);

这显然会比直接加载要慢(而且你需要在上面添加数据库调用)。

【讨论】:

谢谢 Nigel,我会这样测试它。问题是运行 200.000 行需要多长时间。 :( 不知道需要多长时间,这取决于您的数据库和硬件。你也应该为你的 SQL 使用准备好的语句。

以上是关于处理奇怪格式的csv文件的主要内容,如果未能解决你的问题,请参考以下文章

使用 access、asp 和 CSV 处理奇怪的字符

浅谈python对csv文件的处理

csv格式文件用excel打开身份证显示错误

FasterCSV 格式错误

处理CSV文件

用java导出.csv格式的文件