2

たとえば、次のようなファイルがあるとします (実際のコンテンツではなく、16 進ダンプです)。

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

どうやら、空白行は削除されていません。

誰かが私が間違っていることを指摘できますか?

4

2 に答える 2

6

正規表現では、$アサーションは少し混乱する可能性があります。ドキュメントによると、「行末(または最後の改行の前)に一致します」。したがって、おおよそ次のように動作します

(?=\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.
}
于 2013-08-07T12:39:51.143 に答える