Perl - 不能剥离空白行

时间:2013-08-07 11:51:18

标签: regex perl

让我们说,我有一个这样的文件(它不是实际的内容,而是hexdump):

0000000  \r  \n  \r  \n   T   h   i   s       i   s       a       f   i
0000010   l   e  \r  \n                              \r  \n   H   e   r
0000020   e   '   s       s   o   m   e       t   e   x   t  \r  \n
000002f 

如果我运行以下内容:

#!/usr/bin/perl
use strict;
use warnings;
use File::Slurp;
$_ = read_file("file.txt");

s/^\s*$//mg;
print;

产生的输出是:

0000000  \n   T   h   i   s       i   s       a       f   i   l   e  \r
0000010  \n  \n   H   e   r   e   '   s       s   o   m   e       t   e
0000020   x   t  \r  \n

显然,空白行没有被删除。

有谁可以指出我做错了什么?

2 个答案:

答案 0 :(得分:6)

在正则表达式中,$断言可能有点令人困惑。根据文档,它“匹配[es]行的结尾(或在结尾的换行符之前)”。所以它的行为大致类似于

(?=\n\z)|\z

使用/m修饰符,此更改为

(?=\n)|\z

这意味着匹配的子字符串中不包含\n。你想要:

s/^\s*\n//mg;

现在代码中仍有一些问题需要解决。主要是,立即读取整个文件并运行正则表达式是没有意义的。相反,我会这样做:

use strict; use warnings; use autodie;

open my $fh, "<", "file.txt";
while (<$fh>) {
  print if /\S/; # print if this line contains at least one non-space character
                 # this elegantly skips whitespace-only lines.
}

这假设行结尾完全由空格字符组成,以\n结尾。这适用于\r\n\n行结尾。否则,分配自定义行结尾,如

local $/ = local $\ = "\r\n"; # input and output line endings
while (<$fh>) {
  chomp;  # remove line endings
  print if /\S/; # print adds the line ending again.
}

答案 1 :(得分:0)

我自己的多线比赛没有成功,所以我再次将内容分成几行:

#!/usr/bin/perl

use strict;
use warnings;

use File::Slurp;

my $content = read_file("test.txt"); # You should'nt set $_ explicitely

foreach (split(/\r\n/,$content)){
    if ($_ =~ /\S/){
        print $_ . "\n";
    }
}