1

次のようなファイルがあります

HEADER foo bar
garbage
SUBHEADER foo foo bar
other garbage
SUBHEADER foo foo bar bar
HEADER foo baz
SUBHEADER foo bar foo foo
SUBHEADER foo foo foo foo
SOMETHING bar bar bar
HEADER baz baz
SUBHEADER baz bar baz foo

大文字の単語は文字どおりに出現し、対応するand とSOMETHING一緒に検索したい場合、つまり、HEADERSUBHEADER

HEADER foo baz
SUBHEADER foo foo foo foo
SOMETHING bar bar bar

プログラムではかなり些細なことですが、正規表現でできるでしょうか? 否定的なアサーションを使用した解決策を想像することはできましたが、それは非常に読みにくくなります。

4

1 に答える 1

2

SOMETHING の前に最も近い HEADER と SUBHEADER を探している場合は、正規表現で貪欲でない一致が必要だと思います-一度に複数の行に一致する正規表現プロセッサがあると仮定すると、通常は除外されますgrepsedなど。

たとえば、次のようなものです。

(^HEADER.*?$).*?(^SUBHEADER.*?$).*?(^SOMETHING.*?$)

また、' ' は (モードの.ように) 改行に一致し、' '/' ' は (モードのように) 文字列の途中の行頭/行末に一致すると仮定しています。これらは、多くの正規表現の実装で構成可能なオプションです。PCRE_DOTALL^$PCRE_MULTILINE


編集:コメントでレイアウトしたコマンドを変更して、機能するようにしました。

perl -0777 -ne '/.*(^HEADER.*?\n).*(^SUBHEADER.*?\n).*?(^SOMETHING.*?\n)/ms
  and print "$1$2$3*\n"'

(パラノイアのために「m」フラグを追加し、行頭アンカーを再度追加しました。必要に応じて、それらを元に戻すことができます。)

重要なアイデアは、最初に欲張りな全一致パターンを配置し、正規表現マッチャーに HEADER を可能な限り遅く一致させる許可を与えることであることが判明しました。このような固定されていない一致は、最初に暗黙の貪欲な一致があるかのように機能すると予想していましたが、明らかに非貪欲な演算子が存在する場合、そのようには機能しません。

于 2012-11-06T06:31:17.157 に答える