「deny」という単語で始まり、「log」という単語で終わらない構成の行を一致させようとしています。これは非常に初歩的なことのように思えますが、私が調べた多数のフォーラムのいずれにも解決策が見つかりません。私の初心者の考え方は、「^deny.* (?!log$)」を試してみることにしました。私の理解では、「deny」で始まり、その後に行末が log 以外である 0 桁以上の任意の文字が続く文字列が検出されるということです。
2 に答える
のような行を指定するdeny this log
と、^deny.*(?!log$)
正規表現 (サンプルの質問にあったスペースは省略しています) は次のように評価されます。
^deny
「拒否」に一致します。.*
は「0 個以上の任意の文字に一致」を意味するため、「このログ」に一致する可能性があります。^(?!log$)
「次の文字が「ログ」ではなく、行末であることを確認してください。」この場合、それらはそうではありません-それらは単なる行末です-したがって、正規表現は一致します。
代わりに次の正規表現を試してください。
^deny.*$(?<!log)
「文字列の先頭で拒否に一致し、次に行の最後に一致し、ゼロ幅の負の後読みアサーションを使用して、行の最後で一致したものが 'log' ではないことを確認します。」
そうは言っても...
正規表現は、必ずしもその仕事に最適なツールではありません。この場合、次のような単純なブール演算子
if (/^deny/ and not /log$/)
おそらく、次のようなより高度な正規表現よりも明確です
if (/^deny.*$(?<!log)/)
(?!log$)
は、ゼロ幅の否定的な先読みアサーションであり、文字列のこの時点で文字列log
の最後である場合は一致しないことを意味し.*
ますが、正規表現では、最後まですべての文字を貪欲に消費していますそのためlog
、一致 する可能性はありません。
正規表現の実装が後読みをサポートしている場合は、Josh Kelley の回答のように正規表現を使用できます。JavaScript を使用している場合は、
/^deny(?:.{0,2}|.*(?!log)...)$/m
m
フラグは複数行モードを意味し、文字列の開始と終了だけでなく、すべての行の開始と終了を作成して一致させます^
。$
.
3 つが否定的な先読みの後に配置されているため、そこにある場合に一致するスペースがあることに注意してくださいlog
。これらの 3 つのドットを含めると、.{0,2}
オプションを追加して、後ろに 0 から 2 文字の文字列deny
も一致するようにする必要がありました。は、 aまたはbが一致する必要(?:a|b)
がある非キャプチャ グループを意味します。