Questo per motivi storici.
Regexp fu introdotto per la prima volta in Unix ed
nell'utility nei primi anni '70. Sebbene ed
si basava su qed
cui attuazione dagli stessi autori capito regexp più complesso, ed
compreso solo ^
, $
, [...]
, .
, *
e \
per sfuggire tutto quanto sopra.
Ora, quando è emersa la necessità di avere più operatori, è stato necessario trovare un modo per introdurli senza interrompere la compatibilità con le versioni precedenti. Se uno script usasse il s
ed
comando s/foo() {/foo (var) {/g
per sostituire tutte le istanze di foo() {
with foo(var) {
e tu avessi introdotto un operatore (
o {
, questo lo spezzerebbe.
Tuttavia nessuno script lo farebbe s/foo\(\) {/foo\(var\) {/
, perché è lo stesso di s/foo() {/foo(var) {/
e non c'era motivo di scappare (
perché non era un operatore RE. Quindi l'introduzione di un nuovo operatore \(
o \{
non interrompe la retrocompatibilità poiché è molto improbabile che si rompa uno script esistente usando la sintassi precedente.
Quindi, ecco cosa è stato fatto. Successivamente, è \(...\)
stato aggiunto inizialmente solo per il s
ed
comando di fare cose simili s/foo\(.\)/\1bar/
e successivamente come grep '\(.\)\1'
(ma non cose simili \(xx\)*
).
In UnixV7 (1979, quindi quasi un decennio più tardi), una nuova forma di espressioni regolari è stata aggiunta nel nuovo egrep
e le awk
utilità chiamate espressioni regolari estese (poiché sono nuovi strumenti, non c'è compatibilità con le versioni precedenti da rompere). Alla fine, ha fornito la funzionalità disponibile nell'antico Ken Thompson qed
(operatore di alternanza |
, raggruppamento (..)*
) e ha aggiunto alcuni operatori come +
e ?
(ma non aveva la funzione di backref delle espressioni regolari di base).
Successivamente i BSD hanno aggiunto \<
e \>
(sia a BRE che a ERE) e SysV aggiunti \{
e \}
solo a BRE.
Non è molto tempo dopo {
e }
sono stati aggiunti a ERE, con una tale retrocompatibilità. Non tutti l'hanno aggiunto. Ad esempio, GNU awk
fino alla versione 4.0.0 (2011) non supportava a {
meno che non fosse forzato nella modalità di conformità POSIX.
quando GNU grep
fu scritto nei primi anni '90, aggiunse tutte le chicche di BSD e SysV (come \<
, {
) e invece di avere due sintassi regexp separate e motore per BRE ed ERE, implementò gli stessi operatori in entrambi, solo le controparti BRE di (
, ?
, {
, +
devono essere preceduti da una barra rovesciata (per essere compatibile con altre implementazioni BRE). Ecco perché puoi farlo .\+
in GNU grep
(anche se non è POSIX o supportato da altre implementazioni) e puoi farlo (.)\1
in GNU egrep
(anche se non è POSIX o supportato da molte altre implementazioni tra cui GNU awk
).
L'aggiunta di \x
operatori non è l'unico modo per aggiungere più operatori in modo compatibile con le versioni precedenti. Ad esempio, perl
usato (?...)
. È ancora compatibile con le ERE all'indietro in quanto (?=...)
non è valido nelle ERE, lo stesso per .*?
. vim
per operatori simili ha fatto diversamente introducendo \@=
o .\{-}
per esempio.