Warum erzeugt das Regex-Zeichen '?' keine Übereinstimmung in sed?

Warum erzeugt das Regex-Zeichen '?' keine Übereinstimmung in sed?

Ich habe eine Zeichenfolge, die ähnlich ist ../../sdd1und die ich von hier aus abgleichen möchte sdd. Ich versuche, den folgenden sedBefehl zu verwenden:

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

und es wird keine Übereinstimmung gefunden.
Aber wenn ich benutze

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

dann bekomme ich mein Match, sdd.

Meine beste Vermutung ist, dass ich das ?ebenfalls maskieren sollte, ähnlich wie die geschweiften Klammern – ich habe es versucht und es funktioniert, aber ich weiß nicht, warum.

Die Frage ist also, warum der [0-9]?reguläre Ausdruck nicht mit dem 1von übereinstimmt oder warum wir das und die geschweiften Klammern sdd1maskieren müssen ??

Antwort1

Verwendet standardmäßig sedBRE und benötigt -Eoder -rkann ERE verwenden

Zitat ausGNU sed-Handbuch

In GNU sed besteht der einzige Unterschied zwischen einfachen und erweiterten regulären Ausdrücken im Verhalten einiger Sonderzeichen: „?“, „+“, Klammern, geschweifte Klammern („{}“) und „|“.

Bei der grundlegenden Syntax (BRE) haben diese Zeichen keine besondere Bedeutung, sofern ihnen kein Backslash ('\') vorangestellt ist. Bei der erweiterten Syntax (ERE) ist es umgekehrt: Diese Zeichen sind speziell, sofern ihnen kein Backslash ('\') vorangestellt ist.

also, für GNU sed, verwenden

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

fürPOSIX BRE, Ihr zweiter Befehl ist der richtige Weg

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

verwandte Informationen