1. ホーム
  2. regex

[解決済み] 正規表現ネガティブルックアヘッド

2022-03-10 07:34:46

質問

私のホームディレクトリには、Drupalプラットフォームを含むフォルダdrupal-6.14があります。

このディレクトリから、次のコマンドを使います。

find drupal-6.14 -type f -iname '*' | grep -P 'drupal-6.14/(?!sites(?!/all|/default)).*' | xargs tar -czf drupal-6.14.tar.gz

このコマンドが行うのは、フォルダをgzip圧縮することです。 drupal-6.14 のすべてのサブフォルダを除いたものです。 drupal-6.14/sites/ sites/all と sites/default を除く が含まれています。

正規表現について質問です。

grep -P 'drupal-6.14/(?!sites(?!/all|/default)).*'

式は 動作 を使うと、除外したいフォルダをすべて除外することができますが、その理由がよくわかりません。

正規表現を使った一般的な作業である

以下の文字列を除くすべての文字列にマッチします。 しない はサブパターンxを含む。言い換えれば、サブパターンを否定する。

このような問題を解決する一般的な戦略として、負のlookaheadsを使用することは理解している(と思う)のですが、正と負のlook(ahead/behind)の仕組みを納得できるレベルで理解したことがないのです。

長年にわたり、それらに関する多くのウェブサイトを読んできました。PHPやPythonの正規表現マニュアル、その他、以下のようなページです。 http://www.regular-expressions.info/lookaround.html などがありますが、私は一度も 本当に をしっかりと理解することができました。

どなたか、これがどのように機能しているのか、また、同様のことを行う類似の例を示していただけませんか?

-- Update One:

Andomarの回答について:二重の負のルックアヘッドは、単一の正のルックアヘッド文としてより簡潔に表現することができます。

すなわち

'drupal-6.14/(?!sites(?!/all|/default)).*'

に相当する。

'drupal-6.14/(?=sites(?:/all|/default)).*'

???

-- アップデート第2弾。

ランダムとアラン・ムーアのように、二重の負のルックヘッドを正のルックヘッドと交換することはできません。

解決方法は?

負のルックヘッドとは、この位置で、以下の正規表現がマッチしないことを意味します。

簡単な例で説明しましょう。

a(?!b(?!c))

a      Match: (?!b) succeeds
ac     Match: (?!b) succeeds
ab     No match: (?!b(?!c)) fails
abe    No match: (?!b(?!c)) fails
abc    Match: (?!b(?!c)) succeeds

最後の例は 二重否定 を許可しています。 b に続いて c . ネストされた負のルックヘッドが正のルックヘッドになります。 c が存在するはずです。

各例では a がマッチングされます。 lookaheadはあくまで条件であり、マッチしたテキストに追加されることはない。