RegEx:如何找到所有没有双引号的换行符号?



我想删除CSV文件中双引号之间的所有非法换行符LF。

"name", "created"
"David A","2022-04-04"
"Mark
B", "2022-04-09"
"Peter C", "2022-05-01"

文件名为name.csv,例如

现在我可以用

cat name.csv |
| perl -p -e 's/n/!LF_SYMBOL!/g'        
| perl -p -e 's/"!LF_SYMBOL!"/"!EOL!"/g' 
| perl -p -e 's/!LF_SYMBOL!//g'          
| perl -p -e 's/!EOL!/n/g'              
> name_new.csv

但是它很丑。我想删除双引号以外的所有换行符

我试过了

perl -p -e 's/[^"]n//' name.csv

perl -p -e 's/^[^"]n//' name.csv

由于某种原因,都只是移除所有的"n

任何想法?

通常最好使用现有的解析器,而不是编写自己的解析器。这也不例外。

[1]

如果提供了allow_whitespace => 1,它甚至可以容忍逗号后面的空格

所以我会使用这个模块,而不是编写我自己的解析器。

你只需要:

perl -MText::CSV_XS=csv -e'
csv
in => *ARGV,
allow_whitespace => 1,
on_in => sub { s/n//g for @{ $_[1] }; };
' name.csv >name_new.csv

输出:

name,created
"David A",2022-04-04
MarkB,2022-04-09
"Peter C",2022-05-01

如果出于某种原因你想要避免XS,较慢的Text::CSV是一个直接的替代品。


  1. 处理字段换行需要传递binary => 1,这是使用csv函数时的默认值。

如果这是一个有效的CSV文件,则使用库读取它,如Text::CSV。他们没有在字段中嵌入换行符的问题,然后很容易删除那些

use warnings;
use strict;
use feature 'say';
use Text::CSV;
my $file = shift or die "Usage: $0 file.csvn";
my $csv = Text::CSV->new(
{ binary => 1, auto_diag => 1, allow_whitespace => 1 }); 
open my $fh, '<', $file  or die "Can't open $file: $!";
while (my $row = $csv->getline($fh)) { 
s/n+//g for @$row; 
$csv->say(*STDOUT, $row);
}

这也可以在一行代码中完成,如果有一些好处的话。


发布的文本,因为它的存在,不是有效的CSV,不能被库直接解析,因为字段之间缺少逗号。我想这些都是拼写错误,因为问题是"csv";在很多地方。请澄清。

嵌入的换行符被binary属性接受,而逗号后的额外空格(严格无效)被allow_whitespace属性接受。

由于您有一个两列"CSV"类文件,并且您想要的只是删除两个字段内的换行符,因此您可以使用像

这样的解决方案
perl -0777 -i -pe 's/^("[^"]*(?:""[^"]*)*")s*,s*(?1)$/$&=~s!R+!!gr/gme' file.csv

查看主正则表达式演示。当找到匹配时,第二个正则表达式s!R+!!gr删除匹配中的所有换行符。

细节:

  • ^-行开始(由于m标志)
  • ("[^"]*(?:""[^"]*)*")-组1:",除"以外的零个或多个字符,然后是""的零个或多个重复,然后是"以外的零个或多个字符,然后是"(匹配文本双引号用"转义的CSV字段)
  • s*,s*-逗号,其中包含0个或多个空格
  • (?1)—重复组1模式的子程序
  • $-行结束(由于m标志)。

相关内容

  • 没有找到相关文章

最新更新