私は貪欲ではない否定的な一致をしようとしていますが、それもキャプチャする必要があります。これらのフラグを Python で使用しています。re.DOTALL | re.LOCALE | re.MULTILINE、各フィールドがバックスラッシュの新しい行で始まるいくつかのテキスト ファイル 'データベース' の複数行のクリーンアップを実行します。各レコードは \lx フィールドで始まります。
\lx foo
\ps n
\nt note 1
\ps v
\nt note
\ge happy
\nt note 2
\ge lonely
\nt note 3
\ge lonely
\dt 19/Dec/2011
\lx bar
...
各 \ge フィールドには、そのレコード内のどこかに \ps フィールドが 1 つずつあることを確認しようとしています。現在、1 つの \ps の後に複数の \ge が続くことが多いため、上記の 2 つの単独の \ge のようにコピーする必要があります。
必要なロジックのほとんどは次のとおりです。任意の \ps フィールドの後で、別の \ps または \lx に遭遇する前に、\ge を見つけ、次に別の \ge を見つけます。\ps フィールドを 2 番目の \ge の直前までコピーできるように、すべてをキャプチャします。
そして、これが私の非機能的な試みです。これを置き換えます:
^(\\ps\b.*?\n)((?!^\\(ps|lx)*?)^(\\ge.*?\n)((?!^\\ps)*?)^(\\ge.*?\n)
これとともに:
\1\2\3\4\1\5
小さなファイル (34 行) でもメモリ エラーが発生します。もちろん、これが機能したとしても、3 番目または 4 番目の \ge ではなく 2 番目の \ge を処理しようとしているだけなので、複数回実行する必要があります。ですから、その点でのアイデアは私にも興味があります。
更新:少し調整が必要な場合もありましたが、Alan Moore のソリューションはうまく機能しました。悲しいことに、DOTALL をオフにする必要がありました。そうしないと、最初の .* を後続の \ps フィールドを含めて防ぐことができなかったからです。形。しかし、正規表現のドット情報で、(?s) 修飾子について知ってうれしく思いました。これにより、一般的に DOTALL をオフにすることができましたが、それが不可欠な他の正規表現では引き続き使用できます。
これは、私が必要とする1行の形式に要約された、推奨される正規表現です:
^(?P<PS_BLOCK>(?P<PS_LINE>\\ps.*\n)(?:(?!\\(?:ps|lx|ge)).*\n)*\\ge.*\n)(?P<GE_BLOCK>(?:(?!\\(?:ps|lx|ge)).*\n)*\\ge.*\n)
それは機能しましたが、上記の例を変更すると、「注 2」の上に \ps が挿入されました。また、\lxs および \ge2 を \lx および \ge と同じように扱っていました (いくつかの \b が必要でした)。だから、私は少し微調整されたバージョンを使いました:
^(?P<PS_BLOCK>(?P<PS_LINE>\\ps\b.*\n)(?:(?!\\(?:ps|lx|ge)\b).*\n)*\\ge\b.*\n)(?P<AFTER_GE1>(?:(?!\\(?:ps|lx|ge)\b).*\n)*)(?P<GE2_LINE>\\ge\b.*\n)
およびこの置換文字列:
\g<PS_BLOCK>\g<AFTER_GE1>\g<PS_LINE>\g<GE2_LINE>
再度、感謝します!