ブロック内に改行がなく、BEGIN
/END
ステートメントがその行の最初の非スペースであると仮定すると、次のように正規表現を記述します (Perl 表記法; 区切り文字を変更し、コメント、空白、/x
修飾子を使用する場合は削除します別のエンジン)
m{
\n \s* BEGIN \s+ \[ # match the beginning
( (?!\n\s*\n) .)*? # match anything that isn't an empty line
# checking with a negative look-ahead (?!PATTERN)
\n \s* END \s+ ID=X_[^\]]* \] # the ID may not contain "]"
}sx # /x: use extended syntax, /s: "." matches newlines
コンテンツが何でもある場合は、すべてのブロックのリストを作成し、それらを grep するのが最善かもしれません。この正規表現は、任意のブロックに一致します。
m{ (
BEGIN \s+ \[
.*? # non-greedy matching is important here
END \s+ ID=[^\]]* \] # greedy matching is safe here
) }xs
(必要に応じて改行を追加します)
次に、この正規表現に一致する一致のみを保持します。
/ID = X_[^\]]* \] $/x # anchor at end of line
これを行わないと、バックトラッキングによって正しい一致が妨げられる可能性があります([\s\S]*?
含むことができますEND ID=X_
)。あなたの正規表現は、 X_.*
.
したがって、使用するBEGIN\s+\[([/s/S]*?)END\s+ID=(.*?)\]
と — 余分な疑問符に注意してください — 1 つの一致は次のようになります。
BEGIN [
text b
text c
END ID=Y_1]
text aaa
text bbb
BEGIN [
text d
text e
END ID=X_2]
…で失敗する代わりにY_
。貪欲な一致 (変更されていない正規表現) は、ファイル全体が一致する結果となるはずです:(.*)
すべての文字を (ファイルの最後まで) 使い果たし、. が見つかるまで戻ります]
。
編集:
perls 正規表現エンジンを使用している場合は、次の(*FAIL)
動詞を使用できます。
/BEGIN\s+\[(.*?)END\s+ID=(X_[^\]]*|(*FAIL))\]/s
「で始まるIDを持っているX_
か、一致に失敗します」. END ID=X_1]
ただし、これはデータ内の -like ステートメントの問題を解決しません。