ブルート フォース アプローチでは、 をポイントして独自のパイプラインを設定しSTDOUTますtail。これにより、すべてのエラーを出力できるようにtailなり、最後のエラーだけを出力するかどうかは気にする必要があります。
指定しなかったので、合法的な構成行は次の形式であると想定します
Name = some value
簡単なマッチング:
^(行頭から)
\w+(1 つ以上の「単語文字」)
\s+(必須の空白が続きます)
=(その後に等号が続きます)
\s+(より必須の空白)
.+(いくつかの必須の値)
$(列の最後で終了)
一緒に接着すると、
#! /usr/bin/perl
use warnings;
use strict;
# for demo only
*ARGV = *DATA;
my $pid = open STDOUT, "|-", "tail", "-1" or die "$0: open: $!";
while (<>) {
print unless /^ \w+ \s+ = \s+ .+ $/x;
}
close STDOUT or warn "$0: close: $!";
__DATA__
This = assignment is ok
But := not this
And == definitely not this
出力:
$ ./lasterr
そして==間違いなくこれではありません
正規表現では、パターンの最後の発生が必要な場合は、パターン^.*の前に配置します。たとえば、入力の最後の X を Y に置き換えるには、次を使用します。
$ エコー XABCXXXQQQXX | perl -pe 's/^(.*)X/$1Y/'
XABCXXXQQQXY
正規表現の量指定子は貪欲である^ため冗長であることに注意してください。
この手法を問題に適用すると、次のプログラムのように、エラーを含む構成ファイルの最後の行を検索できます。
#! /usr/bin/perl
use warnings;
use strict;
local $_ = do { local $/; scalar <DATA> };
if (/\A.* ^(?! \w+ \s+ = \s+ [^\r\n]+ $) (.+?)$/smx) {
print $1, "\n";
}
__DATA__
This = assignment is ok
But := not this
And == definitely not this
正規表現の構文は、複数の行が含まれているため少し異なり$_ますが、原理は同じです。\Aに似ていますが、検索する文字列の先頭のみ^に一致します。スイッチ (「複数行」)を使用すると、論理的な行の境界で一致します。/m^
ここまででパターンはわかった
/\A.* ^ .../
何かのように見える最後の行に一致します。否定先読みアサーション (?!...)は、有効な構成行ではない行を探します。通常.、改行以外の任意の文字に一致しますが、/sスイッチ (「単一行」)によってこの制限が解除されます。を指定[^\r\n]+すると、つまり、キャリッジ リターンでもライン フィードでもない 1 つ以上の文字が指定された場合、一致が次の行にスピルすることはできません。
ルックアラウンド アサーションはキャプチャしないため、問題のある行を で取得し(.+?)$ます。このコンテキストで安全に使用できる理由は、現在の行が正しくなく、貪欲でない量指定子ができるだけ早く一致を停止すること.がわかっているためです。この場合、現在の論理行の終わりです。+?
これらすべての正規表現は、/xスイッチ (「拡張モード」)を使用して余分な空白を許可します。目的は、読みやすさを向上させることです。