
grep '+'と '*'特殊文字を使用していくつかの簡単なテストを実行しました。
$ echo 'where wh+'> /tmp/toto
$ grep 'wh[e]\*' /tmp/toto
$ grep 'wh[e]*' /tmp/toto
where wh+
$ grep 'wh[e]+' /tmp/toto
$ grep 'wh+' /tmp/toto
$ grep 'wh[e]\+' /tmp/toto
where
$ grep -E 'wh[e]*' /tmp/toto
where wh+
$ grep -E 'wh[e]+' /tmp/toto
where wh+
これらのテストでは、拡張されていないgrep '+'(および '?')は特殊文字として解釈されず、特殊文字として使用するにはエスケープする必要があります。私が知る限り、grepは-Eオプションなしでデフォルトの正規表現を使用します。この場合、特殊文字はここで定義されます。 http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html#tag_09_03 そして'? 「+」はBREの特殊文字ではありません。
しかし、BREで非特殊文字「+」をエスケープすると、特殊文字になるのはなぜですか?
答え1
これはGNU拡張です。 ~からgrep(1)
マンページ:
GNU では、
grep
基本構文と拡張構文の間で使用できる機能に違いはありません。他の実装では、基本正規表現はそれほど強力ではありません。次の説明は拡張正規表現に適用されます。基本正規表現との違いは後で要約されます。
もっと下へ
基本正規表現と拡張正規表現
基本正規表現では、メタ文字、、、、および
?
は+
特別な意味を失います。代わりに、バックスラッシュバージョン、、、、、およびが{
使用されます。|
(
)
\?
\+
\{
\|
\(
\)
答え2
提供したPOSIX仕様リンクから次の内容を読むことができます。
一般文字は、BRE特殊文字にリストされているBRE特殊文字を除いて、サポートされている文字セット内のすべての文字と一致するBREです。
( '\' ) 前に続く一般文字の解釈は、以下を除いて定義されません。
- 文字「)」、「(」、「{」、「}」
- 数字1〜9(含む)(複数の文字に一致するBREを参照)
- 角かっこ式内の文字
したがって、デフォルトでは+
これは通常のBRE文字であるため、動作は指定されておらず、grep 'x\+'
一部の実装(GNUなど)ではこれをgrep
()と同じように扱い、一部は()と同じように扱うことができます。grep 'x\{1,\}'
grep -E 'x+'
grep 'x+'
grep 'x\\+'
したがって、文字列を移植可能に一致させるには(または、または、または)をx\+
作成する必要があります。grep 'x\\+'
grep 'x[\]+'
grep -F 'x\+'
grep -E 'x\\\+'
grep -E 'x[\][+]'
答え3
上記の例があなたに定義された行動に違反しているように見えるかどうかはわかりません。
+を脱出してもルールは変わりません。