php-将格式错误的txt转换为csv

php-将格式错误的txt转换为csv,php,csv,preg-match,Php,Csv,Preg Match,我有一个格式不正确的文本文件,我想转换成csv 下面是一个例子: 100910 NA/1-2013-99636 VIA DEI PESCATORI 2/A LODI APR 8 2013 4:24PM DANNEGGIATO -10% 200 2700 0 0 NO 148013 NA/1-2014-146194 CAVALLOTTI SNC LODI GEN 3 2014 3:37PM DANNEGGIATO -10% 0 0 2 0 NO 160032 NA/1-2014-158129 PA

我有一个格式不正确的文本文件,我想转换成csv

下面是一个例子:

100910 NA/1-2013-99636 VIA DEI PESCATORI 2/A LODI APR 8 2013 4:24PM DANNEGGIATO -10% 200 2700 0 0 NO
148013 NA/1-2014-146194 CAVALLOTTI SNC LODI GEN 3 2014 3:37PM DANNEGGIATO -10% 0 0 2 0 NO
160032 NA/1-2014-158129 PAOLO GORINI SNC LODI MAG 6 2014 11:51AM DANNEGGIATO -10% 2 0 2 0 NO
54900 NA/1-2014-158070 STRADA VECCHIA CREMONESE SNC LODI MAG 6 2014 9:53AM DANNEGGIATO +10% 10 0 10 0 NO
100910 NA/1-2013-99636 VIA DEI PESCATORI 2/A LODI APR 8 2013 4:24PM DANNEGGIATO -10% 200 2700 0 0 NO
147959 NA/1-2014-146140 DOSSENA SNC LODI GEN 3 2014 10:45AM DANNEGGIATO -10% 200 0 200 0 NO
大致是这样的:

[number] [id] [awfully formatted street] ['LODI'] [timestamp] [damaged or not] [percentage] [squaremeters] [squaremeters] [squaremeters] [squaremeters] [asbest-crumbled or not]
我的问题是如何提取第三部分,[格式错误的街道]。 基本上,它是字符串['LODI']前面的[id]后面的字符串(但是['LODI']必须正好在[timestamp]之前)

我是否应该按空格分解()每一行,然后向后遍历数组,超越[timestamp],超越['LODI'],并在数组[id]之前加入值,即数组[1]?或者有没有更聪明(优雅)的方法来做到这一点,也许是使用preg_match()


谢谢你的提示

这应该可以从行中提取地址

<?php 
$row = "100910 NA/1-2013-99636 VIA DEI PESCATORI 2/A LODI APR 8 2013 4:24PM DANNEGGIATO -10% 200 2700 0 0 NO";
$row_array = preg_split('/\s+/', $row);


array_shift($row_array);
array_shift($row_array);

for($i=0; $i<12; $i++){
    array_pop($row_array);
}

$address = implode(" ", $row_array);

?>

我认为爆炸在这里不行。我建议使用regexp。例如,如果将.txt文件作为一个字符串读取(其中数据字符串以\n分隔):

然后像这样使用
preg\u match\u all()

$re = "/^(\\d+)\\s*(.*)(LODI)\\s*(.+(?:AM|PM))\\s*(\\w+)\\s+(-?\\d{1,3}%)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\w+)$/m"; 
preg_match_all($re, $str, $matches,PREG_SET_ORDER );
echo "<pre>\n";
print_r($matches);
echo "</pre>\n";
<?php
    // read file line by line
    $line = '148013 NA/1-2014-146194 CAVALLOTTI SNC LODI GEN 3 2014 3:37PM DANNEGGIATO -10% 0 0 2 0 NO';

    //start by seperating the string on LODI
    $lodi_split = explode('LODI', $line);

    // Now split the first occ into an array on space
    $bits = explode(' ', $lodi_split[0]);

    $address = '';
    // start reading occurance from occ 2 to loose the first 2 fields
    for ($i=2; $i < count($bits); $i++ ) {
        $address .= $bits[$i] . ' ';
    }
    echo $address . PHP_EOL;

我在本例中使用了您上面提供的文本。因此,在输出中,您将接收格式化为数组列表的数据。所以你可以用它做任何你想做的事$matches[$i][0]-将存储整个匹配,因此只需跳过它并使用$matches[$i][1]…..$matches[$i][11]作为数据

是的,谢谢。我想应该是这样的。第一个选择组(.*)看起来很贪婪(它匹配到最后一行的所有文件,preg_match_all()总是只返回最后一行,即模式只出现一次)。很奇怪,因为preg_match_all用m标记,所以我认为它应该逐行读取
CAVALLOTTI SNC
<?php
    // read file line by line
    $line = '148013 NA/1-2014-146194 CAVALLOTTI SNC LODI GEN 3 2014 3:37PM DANNEGGIATO -10% 0 0 2 0 NO';

    //start by seperating the string on LODI
    $lodi_split = explode('LODI', $line);

    // Now split the first occ into an array on space
    $bits = explode(' ', $lodi_split[0]);

    $address = '';
    // start reading occurance from occ 2 to loose the first 2 fields
    for ($i=2; $i < count($bits); $i++ ) {
        $address .= $bits[$i] . ' ';
    }
    echo $address . PHP_EOL;
CAVALLOTTI SNC