ブルート フォース アプローチでは、 をポイントして独自のパイプラインを設定し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
スイッチ (「拡張モード」)を使用して余分な空白を許可します。目的は、読みやすさを向上させることです。