web-dev-qa-db-ja.com

正規表現の。*と*の違い

「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」で終わるものと一致する必要があります。

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

6
ravi

表記(。*)

正規表現。*および*内の*は、カウントごとの文字数ではなく、カウントを指します。より正確には、'zero or more'を意味します。さらに、'任意の1文字'を意味します。

したがって、それらを組み合わせると、'ゼロ以上の任意の文字'が得られます。たとえば、次のような文字列:

  • linux
  • linnnnnx
  • lnx
  • こんにちはLinux
  • lx

<l.*x>と一致します。最後の1つは重要です。。*は何にも一致しないことを示しています。

表記(*)

私が言ったように*だけの使用はカウンターです。つまり、'l'のような文字の後ろに置くと、*は'zero or more of l'と言っています。

l*xをgrepした場合、これはl...xと一致しますが、おそらくあなたが考える理由ではありません。

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

末尾の「x」と一致します。 「l」は、「x」の前に'zero or more l's'が付いているという事実を除いて、これが一致する理由とは関係ありません。

11
slm

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

1
Abijith Kp

ジョーカーを使用してファイル名を一致させるシェル(bashなど)の場合、*および?は文字そのものであり、文字を表します。

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

この違いを思い出したら、シェルと正規表現が*?を使用する方法の間で、適切に機能するはずです。

だから正規表現の場合:

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