将文本文件解析为 4 列,第 3 列有时有值,有时没有(PHP)
Posted
技术标签:
【中文标题】将文本文件解析为 4 列,第 3 列有时有值,有时没有(PHP)【英文标题】:Parse a text file into 4 columns, with the 3rd column sometimes has value and sometimes not (PHP) 【发布时间】:2021-06-29 13:55:51 【问题描述】:大家! 我正在寻求帮助,因为我陷入困境并且不知道......
我需要将一个文本文件解析为 4 列,其中第 3 列有时有值,有时没有。
我尝试了很多选项...例如,将 3,4 空格替换为“分隔符”,将空格替换为另一个特殊字符...但我无法理解如何管理当前行中的 3 或 4 列
我已附上文件的一部分。 谢谢各位!
246/RD/2010 05.01.2010 211/P 12.11.2010
247/RD/2010 05.01.2010 195/P 09.11.2010
248/RD/2010 05.01.2010 13.10.2010
251/RD/2010 05.01.2010 274/P 08.12.2010
996 /RD/2015 19.01.2015 1049/P/04.12.2015
997 /RD/2015 19.01.2015 1049/P/04.12.2015
998 /RD/2015 19.01.2015 1049/P/04.12.2015
999 /RD/2015 19.01.2015 1049/P/04.12.2015
1000 /RD/2015 19.01.2015 1049/P/04.12.2015
1001 /RD/2015 19.01.2015 1049/P/04.12.2015
1002 /RD/2015 19.01.2015 1049/P/04.12.2015
1003 /RD/2015 19.01.2015 1049/P/04.12.2015
1004 /RD/2015 19.01.2015 1049/P/04.12.2015
31600 /RD/2015 10.06.2015 1152/P/12.09.2016
31601 /RD/2015 10.06.2015 690/P/26.05.2016
31605 /RD/2015 10.06.2015 1148/P/12.09.2016
31608 /RD/2015 10.06.2015 1150/P/12.09.2016
149130/RD/2010 13.10.2010 870/P/12.09.2011
149136/RD/2010 13.10.2010 1106/P/09.11.2011
149137/RD/2010 13.10.2010 1107/P/10.11.2011
149138/RD/2010 13.10.2010 868/P/12.09.2011
149139/RD/2010 13.10.2010 870/P/12.09.2011
148931/RD/2010 13.10.2010 1050/P/24.10.2011
148932/RD/2010 13.10.2010 1080/P/03.11.2011
148933/RD/2010 13.10.2010 883/P/13.09.2011
148934/RD/2010 13.10.2010 28.01.2011
148935/RD/2010 13.10.2010 1106/P/09.11.2011
147809/RD/2010 06.10.2010 881/P/13.09.2011
147810/RD/2010 06.10.2010 19.10.2011
147811/RD/2010 06.10.2010 1049/P/24.10.2011
【问题讨论】:
算出每列的宽度和substr
的大小。然后您可以trim()
删除多余的字符。
如果我理解你的答案正确,你解释了如何获取行。获取行不是问题,简单的explode("\n")。我的问题是弄清楚第三列在哪里,第四列在哪里
【参考方案1】:
您的问题可以通过正则表达式解决。但这有点棘手。这是我的缩写。它不关心列之间有多少空间。它匹配列的特定模式以区分它们。
// reduced test-data for simplicity
$data = ' 246/RD/2010 05.01.2010 211/P 12.11.2010
247/RD/2010 05.01.2010 195/P 09.11.2010
248/RD/2010 05.01.2010 13.10.2010
251/RD/2010 05.01.2010 274/P 08.12.2010';
// regular-expression with groups to get your needed columns
$re = '/^\s*([0-9]+\s*[0-9A-Z\/]+)\s+([0-9]2\.[0-9]2\.[0-9]4)\s+([0-9]2\.[0-9]2\.[0-9]4)*(\s*$|([0-9A-Z\/]+\s*[0-9]2\.[0-9]2\.[0-9]4$))/m';
// match it
preg_match_all ($re, $data, $matches, PREG_SET_ORDER, 0);
// $matches is now an multidimensional array with an array for every line.
// those line-arrays will contain columns 1 to 5 where 3 will
// be your third column (sometimes empty) and 5 will be the last column.
// [
// ['246/RD/2010', '05.01.2010', '', '', '211/P 12.11.2010'],
// ['247/RD/2010', '05.01.2010', '', '', '195/P 09.11.2010'],
// ['248/RD/201', '05.01.2010', '13.10.2010', '', ''],
// ['251/RD/2010', '05.01.2010', '', '', '274/P 08.12.2010'],
// ]
【讨论】:
非常感谢!这部分简直令人叹为观止! ([0-9]2\.[0-9]2\.[0-9]4)*(\s*$|([0-9A-Z\/]+\s *[0-9]2\.[0-9]2\.[0-9]4$)) @AlexF 不客气。很高兴我能帮上忙。【参考方案2】:它看起来像一个固定格式的文件,因此它期望每个字段位于每一行中的某个点。您可以使用substr()
提取行的每个部分,其中包含一个起点和该字段应包含的字符数。还可以在结果中使用trim()
删除任何多余的空格。
这只是对字段位置的粗略猜测,您需要检查每个字段的开始位置,您可以看到我从第一列中的日期得到0
...
$file =
' 246/RD/2010 05.01.2010 211/P 12.11.2010
247/RD/2010 05.01.2010 195/P 09.11.2010
248/RD/2010 05.01.2010 13.10.2010
251/RD/2010 05.01.2010 274/P 08.12.2010
';
foreach ( explode(php_EOL, $file) as $line )
if ( !empty($line) )
$c1 = trim(substr($line, 0, 27));
$c2 = trim(substr($line, 27, 14));
$c3 = trim(substr($line, 41, 14));
$c4 = trim(substr($line, 56) ?: '');
echo $c1."###".$c2."###".$c3."###".$c4.PHP_EOL;
这给了...
246/RD/2010 0###5.01.2010######11/P 12.11.2010
247/RD/2010 0###5.01.2010######95/P 09.11.2010
248/RD/2010 0###5.01.2010###13.10.2010###
251/RD/2010 0###5.01.2010######74/P 08.12.2010
我在$c4
上使用了 ?: ''
,以防线条没有完全填充(尽可能全长)。
【讨论】:
【参考方案3】:由于您的文件是固定宽度的文档,您可以使用substr
对其进行解析。在大多数情况下,更好的方法是使用空格as explained here 使用preg_split
,但在您的情况下,最后一列也可以包含空格(例如211/P 12.11.2010
)
因此,最好的方法是计算字符数,并根据substr
创建列。然后,您可以像其他人建议的那样使用 trim
来删除多余的空格。
在代码中
$f = file_get_contents('file.txt');
$f = explode("\n", $f);
$cols = [
[0,25],
[25,13],
[38,16],
[54,18]
];
$result = [];
foreach ($f as $count => $line)
$result[$count] = [];
foreach ($cols as $c)
$result[$count][] = trim(substr($line, $c[0], $c[1]));
var_dump($result);
这会给你类似的结果
array(30)
[0]=>
array(4)
[0]=>
string(11) "246/RD/2010"
[1]=>
string(10) "05.01.2010"
[2]=>
string(0) ""
[3]=>
string(16) "211/P 12.11.2010"
.
.
.
[29]=>
array(4)
[0]=>
string(14) "147811/RD/2010"
[1]=>
string(10) "06.10.2010"
[2]=>
string(0) ""
[3]=>
string(17) "1049/P/24.10.2011"
【讨论】:
以上是关于将文本文件解析为 4 列,第 3 列有时有值,有时没有(PHP)的主要内容,如果未能解决你的问题,请参考以下文章