Antworten:
Es ist wie ?
in vielen anderen Modulen für reguläre Ausdrücke und bedeutet "Keine Übereinstimmung oder eine der vorhergehenden Übereinstimmungen".
In Ihrem Beispiel wird das auf \?
das angewendet [ -]
, was bedeutet, dass versucht wird, ein Leerzeichen oder ein Minuszeichen zuzuordnen, das Leerzeichen oder Minuszeichen jedoch optional ist.
So wird eines dieser übereinstimmen:
555 1234
555-1234
5551234
Der Grund , warum es so geschrieben , \?
anstatt ?
ist für die Abwärtskompatibilität.
Die ursprüngliche Version von grep
verwendete eine andere Art von regulären Ausdrücken, die als "reguläre Basisausdrücke" bezeichnet wurde und ?
nur ein wörtliches Fragezeichen bedeutete.
Damit GNU grep die Null- oder Eins-Funktionalität haben konnte, fügten sie diese hinzu, mussten jedoch die \?
Syntax verwenden, damit die verwendeten Skripte ?
weiterhin wie erwartet funktionierten.
Beachten Sie, dass grep über eine -E
Option verfügt, die die Verwendung des allgemeineren Typs regulärer Ausdrücke ermöglicht, der als "erweiterte reguläre Ausdrücke" bezeichnet wird.
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 \).
Weitere Infos:
grep -E
ist der offizielle POSIX-Weg. egrep
wurde in susv2 (1997) veraltet und in susv3 (2001) aus den POSIX- und Unix-Spezifikationen entfernt.
\?
ist allerdings ein GNUism.
Leider unterscheidet sich die genaue Syntax regulärer Ausdrücke zwischen verschiedenen Programmen geringfügig: reguläre Ausdrücke für grep sind nicht identisch mit regulären Ausdrücken für sed, die nicht identisch mit regulären Ausdrücken für Emacs sind, die nicht identisch mit regulären Ausdrücken für C ++ sind auf. Erschwerend kommt hinzu, dass sogar ein "Standard" -Tool wie grep zwischen verschiedenen Unix-ähnlichen Betriebssystemen leicht variieren kann.
In einer Regex haben einige Zeichen eine spezielle Bedeutung (wie die eckigen Klammern in Ihrem Beispiel) und kehren zu ihrer normalen Bedeutung als wörtliche Zeichen zurück, wenn Sie sie durch einen umgekehrten Schrägstrich "entkommen" (so würde es eine wörtliche Klammer sein) geschrieben als \ [). Andere arbeiten umgekehrt und erhalten nur dann eine besondere Bedeutung, wenn sie maskiert werden (z. B. n ist nur ein Buchstabe, aber \ n ist ein Zeilenvorschub). Und diese können wiederum zwischen Regex-Implementierungen variieren.
In den meisten Regex-Implementierungen bedeutet ein Fragezeichen, dass das vorherige Element optional ist, während ein maskiertes Fragezeichen (\?) Ein wörtliches Fragezeichen ist. In einigen Dialekten ist es jedoch umgekehrt. Ihr Beispiel könnte so oder so Sinn machen, aber ich vermute, Sie haben einen der Dialekte, in denen? ist ein wörtliches und \? ist das optionale Symbol. Ihre Regex bedeutet also wahrscheinlich "drei Ziffern, optional gefolgt von einem Leerzeichen oder Bindestrich, gefolgt von vier Ziffern".
(Ein weiterer Hinweis kann in Konstrukten wie \ {3 \} gesehen werden, die eindeutig "genau 3 des vorherigen Elements" bedeuten sollen. In den meisten Regex-Dialekten wäre dies {3} und \ {wäre eine wörtliche Klammer .)
Dies ist eine kurze Zusammenfassung der Informationen, die bereits in den anderen Antworten enthalten sind.
In grep
, ?
entspricht einem wörtlichen Fragezeichen und \?
bezeichnet null oder ein Vorkommen dessen, was davor steht. Im Beispiel in Ihrer Frage [ -]\?
entspricht dies entweder einem Leerzeichen oder einem Bindestrich oder gar nichts.
In egrep
oder grep -E
ist es umgekehrt; \?
Entspricht einem wörtlichen Fragezeichen und gibt ?
null oder ein Vorkommen an.
Dies gilt für GNU grep; Die Details für Nicht-GNU-grep-Implementierungen können geringfügig abweichen. Insbesondere grep
und egrep
historisch gesehen waren es zwei getrennte Programme, und ich glaube nicht, dass alte grep
die -E
Option hatten. POSIX gibt an grep -E
, aber (ich war überrascht zu entdecken) nicht zu erwähnen egrep
.
egrep
Befehl ist äquivalent zugrep -E
. Bei anderen Versionen als GNU grep wirdgrep
die-E
Option möglicherweise akzeptiert oder nicht , und es handelt sichegrep
möglicherweise um ein separates Programm.