7桁の電話番号を検索するには、次のコマンドを使用します。
grep "[[:digit:]]\{3\}[ -]\?[[:digit:]]\{4\}" file
\?
何を表すか?
答え1
他の多くの正規表現エンジンと同様に、?
「0以前のものと一致」を意味します。
あなたの例では、\?
に適用されます[ -]
。つまり、スペースまたはマイナス記号と一致しようとしますが、スペースまたはマイナス記号はオプションです。
したがって、次のいずれかが一致します。
555 1234
555-1234
5551234
以前のバージョンとの互換性のために書かれた\?
ものではありません?
。
元のバージョンでは、grep
「基本正規表現」という別のタイプの正規表現を使用していましたが、ここでは文字通り?
疑問符のみが表示されていました。
\?
彼らはGNU grepが0または1つの機能を持つようにこれを追加しましたが、使用されたスクリプトがまだ?
期待どおりに機能するように構文を使用する必要がありました。
grepには、-E
「拡張正規表現」というより一般的な型の正規表現を使用するオプションがあります。
man 1 grep
:
-E, --extended-regexp
Interpret PATTERN as an extended regular expression
(ERE, see below). (-E is specified by POSIX.)
-G, --basic-regexp
Interpret PATTERN as a basic regular expression (BRE, see below).
This is the default.
...
Repetition
A regular expression may be followed by one of several repetition operators:
? The preceding item is optional and matched at most once.
...
grep understands three different versions of regular expression syntax:
“basic,” “extended” and “perl.”
...
Basic vs Extended Regular Expressions
In basic regular expressions the meta-characters ?, +, {, |, (, and )
lose their special meaning; instead use the backslashed versions
\?, \+, \{, \|, \(, and \).
追加情報:
grep -E
オプションとegrep
- GNU grep - 基本と拡張
- 正規表現構文の概要
- 正規表現 - Wikipedia
- いくつかの正規表現コマンドが他の文字に対して「\」を逆に解釈するのはなぜですか?
答え2
残念ながら、正規表現の正確な構文はプログラムごとに少し異なります。 grep 正規表現は sed 正規表現とまったく同じではなく、Emacs 正規表現とまったく同じではなく、Emacs 正規表現もまったく同じではありません。これはC ++正規表現とまったく同じではありません。正規表現はまったく同じではありません。悪いことに、grepのような「標準」ツールもUnixシリーズのオペレーティングシステムによって少し異なります。
正規表現では、一部の文字には特別な意味(例:大括弧)があり、文字の前にバックスラッシュを配置して「エスケープ」すると、リテラル文字としての一般的な意味に戻ります(したがって、リテラル括弧は\ [)で使用します。対照的に、他のものはエスケープされた場合にのみ特別な意味を持ちます(たとえば、通常のnは文字だけですが、\ nは改行文字です)。繰り返しますが、これは正規表現の実装によって異なる場合があります。
ほとんどの正規表現の実装では、疑問符は前の項目がオプションであることを意味し、エスケープされた疑問符(\?)は文字通りの疑問符を意味します。しかし、いくつかの方言では、その逆は本当です。あなたの例はどちらにも意味がありますが、どこに方言があると思いますか?リテラルで \? はオプションの記号です。したがって、正規表現は「3桁の数字、オプションでスペースまたはダッシュ、4桁の数字」を意味できます。
(別の手がかりは、「前の項目の正確に3つ」を意味する\ {3 \}のような構文で見ることができます。ほとんどの正規表現方言では、これは{3}で書かれていますが、\ {は文字通り中括弧です。)
答え3
以下は、すでに他の回答に含まれている情報の簡単な要約です。
は、grep
文字通り?
の疑問符の文字と一致し、\?
その前にある内容が0個または1個発生することを示します。したがって、質問の例では、[ -]\?
スペースやハイフンを一致させたり、何も一致させたりしないでください。
egrep
または では、grep -E
その逆は事実です。\?
文字通りの疑問符と一致するということは、?
0個または1個の発生を意味します。
これはGNU grepに適用されます。 GNU以外のgrep実装の詳細は若干異なる場合があります。特にとはgrep
歴史的に2つの別々のプログラムなので古いプログラムにはオプションがegrep
ないと思います。 POSIXではこれを指定しましたが(驚くべきことに)言及していません。grep
-E
grep -E
egrep