grep コマンドのパターン (^[0-9]..[a-zA-Z ]+$) に一致する表現は何ですか? Linux bash

grep コマンドのパターン (^[0-9]..[a-zA-Z ]+$) に一致する表現は何ですか? Linux bash

正規表現がコマンド(Linuxターミナル)(^[0-9]..[a-zA-Z ]+$)で正確にどのような表現を検出するかを理解しようとしていますgrep

次のコマンドを記述すればわかります:

grep ^[0-9]..[a-zA-Z] filename.txt

次のような表現を含む行を検出しますが、その意味やコマンドで検出できる表現の種類は92afg わかりません。+$

grep ^[0-9]..[a-zA-Z]+$ filename.txt

新しいテキスト ファイルを開いて、検出されると思われる表現を入力しようとしましたが、どれも一致しませんでした。この点について説明していただければ幸いです。

答え1

詳しく見ていきましょう。まず、この正規表現は「拡張正規表現」構文 (ERE) - は、がデフォルトで使用する+「基本正規表現」構文では機能しないメタ文字ですgrep(つまり、それ自体に一致し、その位置にリテラルが必要になります+)。そのため、 でその RegEx を使用する場合はgrep、 オプションを渡す必要があります-E

  • ^、正規表現のこの位置を行の先頭に結び付けるアンカーです。
  • は文字リストであり、からまでのソート範囲に含まれる任意の[0-9]単一(1)文字と一致します。 正確に何が含まれるかは、環境変数 などによって決定される「照合順序」によって異なります。09LC_COLLATE
  • .任意の 1 文字に一致するため、two は..「任意の 2 文字」を意味します。
  • [a-zA-Z]文字リストであり、との間にある文字(1)aと、とzの間にある文字に一致します。 繰り返しますが、その意味は照合順序によって異なります。AZ
  • +「前の1つ以上」を意味します。
  • $、正規表現のこの位置を行末に結び付けるアンカーです。

つまり、正規表現意図をもって(1)以下の行に一致する

  • 任意の数字で始まる
  • 任意の2文字が続く
  • 行末までの文字(少なくとも 1 文字)のみが含まれます。

(1)それが実際に何をするのかについては、以下を参照のこと

いくつかのメモ

  1. この例では、引用符なしで正規表現を使用しています。つまり、文字はコマンドに渡される前にシェルによって解釈される可能性がありますgrep。パターンに$またはグロブ文字 ( *?および[...]文字リスト) が含まれている場合、シェルは変数の展開 (それによって RegEx の一部を置き換えます) を実行しようとしたり、グロブパターンを複数のファイル名に展開したりして、最終的に当初意図していたよりも多くの引数をコマンドラインに持つことになります。シェルに固有の他の文字 ( >、など) を使用すると、さらに予期しない動作が発生する可能性があります#;

    grep -E '^[0-9]..[a-zA-Z]+$' filename.txt
    

    -x代わりに、フラグを使用して「行全体」の一致を強制することで、開始アンカーと終了アンカーを削除できることに注意してください。

    grep -x -E '[0-9]..[a-zA-Z]+' filename.txt
    
  2. 範囲を含む文字リスト( などa-z)は危険ななぜなら、期待どおりの結果にならないかもしれないからです。単純に考えると、ASCIIテーブルの開始文字と終了文字の間にあるすべての文字に一致すると期待するかもしれませんが、それはロケールにのみ当てはまりますC。他のロケール(特に、通常設定されているシステムロケールなどen_US.UTF-8)では、照合順序は次のようになりaAbB ... zZますa-z。したがって、ほとんどの大文字にも一致します。また、一致は実際には単一の文字のレベルではなく、「照合要素」のレベルであり、一部のロケールでは、複数の文字の組み合わせ一致する可能性があります(例:dzsハンガリー語)!この答え(または、一般的には、@Stéphane Chazelasによるパターンマッチングに関するほとんどの回答)を参照してください。範囲が機能することを確認したい場合は、指定されたコマンドの照合順序を少なくとも次のように設定してください。

    LC_COLLATE="C" grep -E ' ... ' filename.txt
    

答え2

+は「前のものの 1 回以上の繰り返し」を意味し、 は$「行末」を意味します。*with が「0 回以上の繰り返し」を意味するのとの違いに注意してください。

つまり、基本的には次のようになります: 数字で始まり、その後に任意の 2 つの文字が続き、その後に 1 つ以上の (大文字の場合もある) 文字¹ が行の終わりまで続く行。

è(¹ 注意してください。一部のロケールでは、言語によってはAZ や az などの 26 文字しか使用できない場合がありますŷ)

正規表現に関する良いガイドとして、私は強く推奨しますグリモアの美しいウェブサイトsed、私はこれを、例えば や にも心からお勧めしますawk


なぜ一致しないのでしょうか?

+拡張正規表現の一部です (それ以外の場合はリテラルの+- 記号として解釈されます)。

したがって、+「1 回以上の繰り返し」として使用する場合は、-E- フラグを使用しgrep、シェルの特殊文字に関する問題を回避できるように正規表現を引用符で囲みます。

grep -E '^[0-9]..[a-zA-Z]+$' filename.txt

関連情報