regex - Perl - 无法去除空行

标签 regex perl

假设我有一个这样的文件(不是实际内容,而是十六进制转储):

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

显然,空行没有被删除。

谁能指出我做错了什么?

最佳答案

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

(?=\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.
}

关于regex - Perl - 无法去除空行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18102670/

相关文章:

php - PHP字符串控制台参数数组

linux - 在另一个文本文件中存在的文本之后打印特定行

eclipse - 在 Perl 中使用 "use"时编译失败

linux - 如何使用正则表达式判断一个文件是否包含ISBN系列?

java - 使用java从文本中删除url时出现问题

python - 问题匹配包含撇号的字符串

perl - 如何在 Perl 的上层范围内本地化变量?

perl - mysql_skip_secure_auth 不跳过安全身份验证

java - 在java中使用正则表达式提取两个特定单词之间的子字符串

python - 正则表达式将唯一字符串提取到新列,出现错误 "look-behind requires fixed-width pattern"