迭代php中的文本文件,多行作为一次迭代或子迭代

时间:2017-09-02 20:57:26

标签: php loops

我正在尝试使用php将基于文本的会计文件转换为数组。每个验证行的结构如下:

#VER A 14 20160715 "mats" 20161016
{
#TRANS 1930 {} -3000.00 20160715 "mats"
#TRANS 2893 {} 3000.00 20160715 "mats"
}
#VER A 15 20160719 "Mats" 20161016
{
#TRANS 1930 {} -20000.00 20160719 "Mats"
#TRANS 2893 {} 20000.00 20160719 "Mats"
}

所以我不想迭代从#VER开始的每一行,然后在花括号{}之间以#TRANS开头的行。子问题部分有问题。我的目标是下面的数组(希望没有错误......)

Array
(
[#VER] => Array
    (
        [A14] => Array
            (
                [verdatum] => 20160714
                [vertext] => mats
                [trans] => Array
                    (
                        [0] => Array
                            (
                                [transaccount] => 1930
                                [transamount] => -3000.00
                                [transdate] => 20160715
                                [transtext] => mats
                            )
                        [1] => Array
                            (
                                [transaccount] => 2893
                                [transamount] => 3000.00
                                [transdate] => 20160715
                                [transtext] => mats
                            )

                    )   
            )
        [A15] => Array
            (
                [verdatum] => 20160719
                [vertext] => Mats
                [trans] => Array
                    (
                        [0] => Array
                            (
                                [transaccount] => 1930
                                [transamount] => -20000.00
                                [transdate] => 20160719
                                [transtext] => Mats
                            )
                        [1] => Array
                            (
                                [transaccount] => 2893
                                [transamount] => 20000.00
                                [transdate] => 20160719
                                [transtext] => Mats
                            )

                    )   
            )
    )

)
到目前为止

代码:

foreach($contentsarray as $line_value)
{

    if (substr($line_value,0,4)=="#VER") {
        list($ver, $serie, $vernr, $verdatum, $vertext, $verregdatum, $versign) = str_getcsv($line_value, ' ');
        $verif[$ver][$serie.$vernr]['verdatum']= $verdatum;
        $verif[$ver][$serie.$vernr]['vertext']= $vertext;

    WHAT TO DO HERE?

    }

}

任何指导都非常感谢。

3 个答案:

答案 0 :(得分:1)

我会选择正则表达式:

$fileContent = file_get_contents($filePath);
if( preg_match_all('/^#VER(.*)\n{\n((^#TRANS.*\n)+)}/m', $fileContent, $matches) ){
   foreach($matches[0] as $i=>$match){
      echo 'VER    : '.$matches[1][$i].PHP_EOL;
      echo 'TRANSes: '.$matches[2][$i].PHP_EOL;
   }
}
所需输出的

更新

$fileContent = file_get_contents($filePath);
if( preg_match_all('/^#VER(.*)\n{\n((^#TRANS.*\n)+)}/m', $fileContent, $matches) ){
   foreach($matches[0] as $i=>$match){
      echo 'VER:'.$matches[1][$i].PHP_EOL;
      if( preg_match_all('/^#TRANS (\d+) {} (-?\d+\.\d+) (\d{8}) "(.*)"/m', $matches[2][$i], $matches2) ){
         foreach($matches2[0] as $j=>$match2){
            $trans = array( 'account' => $matches2[1][$j]
                          , 'amount'  => $matches2[2][$j]
                          , 'date'    => $matches2[3][$j]
                          , 'text'    => $matches2[4][$j]
                          );
            print_r($trans);
         }
      }
   }
}

答案 1 :(得分:0)

关于Sals解决方案。看起来很有趣。试图建立它,但得到一个奇怪的输出。这段代码:

if( preg_match_all('/^#VER(.*)\n{\n((^#TRANS.*\n)+)}/m', $fileContent,     $matches) ){
       foreach($matches[0] as $i=>$match){
          echo 'VER    : '.$matches[1][$i].PHP_EOL; echo "</br>";
          foreach($matches[2] as $x=>$match2){
            echo 'TRANS: '.$matches[2][$x].PHP_EOL; echo "</br>";
          }
       }
    }

生成:

VER : A 14 20160715 "mats" 20161016 
TRANS: #TRANS 1930 {} -3000.00 20160715 "mats" #TRANS 2893 {} 3000.00 20160715 "mats" 
TRANS: #TRANS 1930 {} -20000.00 20160719 "Mats" #TRANS 2893 {} 20000.00  20160719 "Mats" 

VER : A 15 20160719 "Mats" 20161016 
TRANS: #TRANS 1930 {} -3000.00 20160715 "mats" #TRANS 2893 {} 3000.00 20160715 "mats" 
TRANS: #TRANS 1930 {} -20000.00 20160719 "Mats" #TRANS 2893 {} 20000.00 20160719 "Mats"

希望得到以下内容:

VER : A 14 20160715 "mats" 20161016 
TRANS: #TRANS 1930 {} -3000.00 20160715 "mats" 
TRANS: #TRANS 2893 {} 3000.00 20160715 "mats" 
VER : A 15 20160719 "Mats" 20161016 
TRANS: #TRANS 1930 {} -20000.00 20160719 "Mats" 
TRANS: #TRANS 2893 {} 20000.00  20160719 "Mats"

答案 2 :(得分:0)

Sal的解决方案似乎正在提供一个有效的解决方案。将代码更改为以下以构建我想要的数组。一个小问题是,当$ fileContent是存储在脚本中的字符串时,下面的工作正常,但是当更改为上传的文件时,代码不会输出数组。关于这可能是什么原因的任何想法?谷歌搜索,也许尾随空格停止代码?

$fileContent = iconv('CP437','UTF-8', file_get_contents($_FILES['userfile']['tmp_name']));
    if( preg_match_all('/^#VER(.*)\n{\n((^#TRANS.*\n)+)}/m', $fileContent, $matches) ){
       foreach($matches[0] as $i=>$match){
            list($ver, $serie, $vernr, $verdatum, $vertext, $verregdatum, $versign) = str_getcsv($matches[1][$i].PHP_EOL, ' ');
            $verif[$ver][$serie.$vernr]['verdatum']= $verdatum;
            $verif[$ver][$serie.$vernr]['vertext']= $vertext;

            if( preg_match_all('/^#TRANS (\d+) {} (-?\d+\.\d+) (\d{8}) "(.*)"/m', $matches[2][$i], $matches2) ){
             foreach($matches2[0] as $j=>$match2){
                $verif[$ver][$serie.$vernr]['trans'][$j] = array( 'account' => $matches2[1][$j]
                              , 'amount'  => $matches2[2][$j]
                              , 'date'    => $matches2[3][$j]
                              , 'text'    => $matches2[4][$j]
                              );
             }
          }
       }
    print "<pre>";
    print_r($verif);
    print "</pre>";


    }