単語を含まない行に一致する正規表現 質問する

単語を含まない行に一致する正規表現 質問する

単語を一致させてから、他のツール (例 ) を使用して一致を反転することは可能です。ただし、正規表現を使用してgrep -v、特定の単語 (例 ) を含まない行を一致させることは可能ですか?hede

入力:
hoho
hihi
haha
hede
コード:
grep "<Regex for 'doesn't contain hede'>" input
望ましい出力:
hoho
hihi
haha

ベストアンサー1

正規表現が逆マッチングをサポートしていないという考えは完全に正しいわけではありません。否定的な参照を使用することでこの動作を模倣できます。

^((?!hede).)*$

上記の正規表現は、(サブ)文字列 'hede' を含まない、任意の文字列または改行のない行と一致します。前述のように、これは正規表現が得意とする (または行うべき) ことではありませんが、それでも可能です

改行文字も一致させる必要がある場合は、ドット-オール修飾子s(次のパターンの末尾):

/^((?!hede).)*$/s

またはインラインで使用します:

/(?s)^((?!hede).)*$/

( は/.../正規表現の区切り文字であり、パターンの一部ではありません)

DOT-ALL 修飾子が使用できない場合は、文字クラスを使用して同じ動作を模倣できます[\s\S]

/^((?!hede)[\s\S])*$/

説明

文字列は単なる文字のリストですn。各文字の前後には空の文字列があります。つまり、n文字のリストには空の文字列が含まれますn+1。次の文字列を考えてみましょう"ABhedeCD"

    ┌──┬───┬──┬───┬──┬───┬──┬───┬──┬───┬──┬───┬──┬───┬──┬───┬──┐
S = │e1│ A │e2│ B │e3│ h │e4│ e │e5│ d │e6│ e │e7│ C │e8│ D │e9│
    └──┴───┴──┴───┴──┴───┴──┴───┴──┴───┴──┴───┴──┴───┴──┴───┴──┘
    
index    0      1      2      3      4      5      6      7

ここで、e's は空の文字列です。正規表現は、表示される(?!hede).部分文字列がないかどうかを先読みし、その場合 (つまり何か他のものが見つかった場合)、(ドット) は改行以外の任意の文字と一致します。ルックアラウンドは文字を消費しないため、ゼロ幅アサーションとも呼ばれます。何かをアサート/検証するだけです。"hede".

したがって、私の例では、"hede"文字が (ドット) によって消費される前に、すべての空の文字列が最初に検証され、その前に何もないかどうかが確認されます.。正規表現は(?!hede).これを 1 回だけ実行するため、グループで囲まれ、0 回以上繰り返されます: ((?!hede).)*。最後に、入力の開始と終了が固定され、入力全体が消費されていることを確認します:^((?!hede).)*$

ご覧のとおり、"ABhedeCD"ではe3正規表現(?!hede)が失敗するため、入力は失敗します (先にがあり "hede"ます)。

おすすめ記事