単語を一致させてから、他のツール (例 ) を使用して一致を反転することは可能です。ただし、正規表現を使用して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"
ます)。