正規表現における .* と * の違い

正規表現における .* と * の違い

「test」という名前のファイルがあり、その中には

linux
Unixlinux
Linuxunix
it's linux
l...x

今、 を使用するとgrep '\<l.*x\>'、一致します:

linux
it's linux
l...x

しかし、 を使用するとgrep '\<l*x\>'、次のものにのみ一致します:

l...xただし、リファレンスガイドによると、*を使用すると、前の項目が0回以上一致します。つまり、「l」で始まり「x」で終わるものに一致するはずです。

望ましい結果が表示されない理由、または私が間違って理解している理由を誰か説明できますか?

答え1

表記法 (.*)

正規表現.*と*の*は文字数ではなくカウント数を指し、より正確には「0以上」さらに、手段「任意の1文字」

これらを組み合わせると「0 個以上の任意の文字」たとえば、次のような文字列です。

  • リナックス
  • リンクス
  • リンクス
  • こんにちはLinux
  • 1x 10進数

と一致します<l.*x>。最後のは重要です。.*何も一致できません。

表記法(*)

先ほど言ったように、*を単独で使うのはカウンターです。そのため、*を文字の後に置くと、'l'*は言っている「l の 0 個以上」

を grep するとl*x、 に一致しますl...xが、おそらくあなたが考える理由とは異なることに注意してください。

% echo "l...x" | grep "l*x"
l...x

これは末尾の「x」に一致しています。「x」の前に「l」があること以外、これが一致している理由には何の関係もありません。「0個以上のl」

答え2

「l」で始まり「x」で終わるものに一致させたい場合、正規表現「l.*x」を試してください。ここで、「.」と「*」は、それぞれ 1 つの有効な文字と長さが 0 以上の文字を表す特殊文字です。ここで「*」の前にあるのは「.」なので、「.」の代わりに来るものはすべて、上記の「*」の定義に従って繰り返されます。

答え3

シェル (例: bash) では、ジョーカーがファイル名の一致に使用される場合、*文字?自体が文字を表します。

一方、正規表現の場合、、、*(出現範囲)および(のみ)は?、それ自体では意味を持ちません。これらは常に、前の文字/アトム(実際の文字(例、または))、(ジョーカー)(任意の文字、文字の範囲(例)、または複数の文字のパターン(egrep のみ。例- ここで「abba」は単位と見なされます)を表すことができるかどうかを参照します。したがって、およびはそれ自体では意味を持ちませんが、前の文字(任意の文字または単位として扱われるグループのジョーカーである可能性があります)を何回繰り返す必要があるかを示します。{n,m}+egrepL5.[a-f](abba)*?

*シェルと正規表現がと を使用する方法の違いを覚えておけば?、すべてが理解できるはずです。

正規表現の場合:

  • .- 任意の文字の1つの出現を表す
  • a..a- 2つのaと、その間の任意の2つの文字に一致します
  • .*- 任意の文字の0、1回以上の出現に一致します
  • B*- 「B」の0回、1回以上の出現に一致します

関連情報