我正在尝试使用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?
}
}
任何指导都非常感谢。
答案 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>";
}