正規表現文字「?」が sed で一致しないのはなぜですか?

正規表現文字「?」が sed で一致しないのはなぜですか?

これに似た文字列があり../../sdd1、ここから一致させようとしていますsdd。次のsedコマンドを使用しようとしています:

echo "../../sdd1" | sed 's:.*\([a-z]\{3\}\)[0-9]?:\1:' 

一致は得られません。
しかし、

echo "../../sdd1" | sed 's:.*\([a-z]\{3\}\)[0-9]\{0,1\}:\1:'

それから私は試合に出場しますsdd

私の推測では?、中括弧と同様に、 もエスケープする必要があると思います。試してみたところ、うまくいきましたが、理由はわかりません。

では、疑問は、なぜ正規表現がfrom に[0-9]?一致しないのか、またはなぜ と中括弧をエスケープする必要があるのか​​ということです。1sdd1?

答え1

デフォルトではBREを使用し、 EREを使用するにはオプションが必要sedです。-E-r

引用元GNU sed マニュアル

GNU sed では、基本正規表現と拡張正規表現の唯一の違いは、いくつかの特殊文字の動作にあります: '?'、'+'、括弧、中括弧 ('{}')、および '|'。

基本 (BRE) 構文では、これらの文字は、バックスラッシュ ('\') が前に付かない限り特別な意味を持ちません。一方、拡張 (ERE) 構文では逆になり、これらの文字は、バックスラッシュ ('\') が前に付かない限り特別な意味を持ちます。

したがって、 についてはGNU sed

$ echo '../../sdd1' | sed 's:.*\([a-z]\{3\}\)[0-9]\?:\1:'
sdd
$ echo '../../sdd1' | sed -E 's:.*([a-z]{3})[0-9]?:\1:'
sdd

のためにPOSIX BRE2番目のコマンドが正しい方法です

$ echo '../../sdd1' | sed 's:.*\([a-z]\{3\}\)[0-9]\{0,1\}:\1:'
sdd

関連情報