csv 如何修复正则表达式查找换行符后的非数值

b5buobof  于 2023-05-20  发布在  其他
关注(0)|答案(2)|浏览(125)

我试图找出正则表达式,并使用PHP来修复csv文件。csv文件的格式应该是这样的:

id, text field1, text field2
1,some text,another text
2,some text,another text
3,some text,another text

问题是,有时,“text field1”中有一个新的行字符,csv文件的内容变成这样:

id, text field1, text field2
1,some text,another text
2,some 
text,another text
3,some text,another text

因此,当逐行阅读文件,或使用新行分解以逐行填充数组时,我会得到无效记录。我使用以下代码解决了上述问题:

<?php
$c= file_get_contents($myFile);
$c= preg_replace( '/\n([^0-9])/is', "\n~~$1", $c );
$c= str_replace( "\n~~", " ", $c );
?>

上面的正则表达式检查换行符后面的字符是否不是数字,然后在那里添加一个~~符号,我用白色替换换行符和~~符号。
问题是,有时,“文本字段1”中有数字,并且换行符就在它们之前出现,如下所示:

id, text field1, text field2
1,some text,another text
2,some 
1999-06-21 text,another text
3,some text,another text

在这种情况下,我的正则表达式没有输入~~符号,我得到了一个损坏的csv文件。
我如何修改上面的正则表达式来解决这个问题?我希望有一个正则表达式,它可以检查“非数值(任何长度)后跟逗号”。请注意,我在csv文件中有超过100000条记录,所以如果使用正则表达式方法,那么正则表达式必须检查任何长度的非数字值。
就像这样:

$c= preg_replace( '/\n([^0-9]*\,)/is', "\n~~$1", $c);

但是上面的正则表达式不起作用,我不知道多少正则表达式来让它起作用。
如果有任何其他方法来修复这个csv文件,即使是确定的。它不必是正则表达式解决方案。
谢谢

rvpgvaaj

rvpgvaaj1#

我不会一行一行地读,因为一个字符串中可以有一些新的行是完全正确的。但是这个CSV文件中缺少的是字符串周围的一些双引号。如果text field1text field2中有逗号,会发生什么?它会破坏你的CSV甚至更多。
由于您无法更正CSV源以正确输出,我们可以根据逗号分割内容(如果我们认为您在文本中没有得到一些)。正如你所知道的,我们只有3个字段,我们知道它应该理想地匹配如下内容:

(\d+),([^,]*),([^,]*?)(?:\r?\n|$)

你可以在这里测试:https://regex101.com/r/YLnNOY/2
在PHP中:

<?php

$regex = '/(\d+),([^,]*),([^,]*?)(?:\r?\n|$)/';

$wrong_csv = 'id, text field1, text field2
1,some text,another text
2,some text,another text
3,some text,another text
1,some text,another text
2,some 
text,another text
3,some text,another text
1,some text,another text
2,some 
1999-06-21 text,another text
3,some text,another text';

$replacement = '$1, "$2", "$3"' . "\n";

$corrected_csv = preg_replace(
    $regex,
    $replacement,
    $wrong_csv
);

print $corrected_csv;

你可以在这里运行PHP demo:https://onlinephp.io/c/8aa48

tsm1rwdh

tsm1rwdh2#

在这种情况下,可以使用negative lookahead\n(?!\d+,)(替换``,跳到替换)。
它匹配任何没有紧跟number,的换行符。
结果,你的代码看起来像这样:

<?php
$c= file_get_contents($myFile);
$c= preg_replace( '/\n(?!\d+,)/g', " ", $c );
?>

演示here
重要的是要注意,这种解决方案仍然容易出错,如果在你的单元格中的换行符后面紧跟着数字和逗号,但要深入纠正这个问题,将需要知道确切的预期格式的行,并检查它,而不仅仅是换行符。

相关问题