Questo per motivi storici.
Regexp fu introdotto per la prima volta in Unix ednell'utility nei primi anni '70. Sebbene edsi basava su qedcui attuazione dagli stessi autori capito regexp più complesso, edcompreso 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 edcomando s/foo() {/foo (var) {/gper 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 edcomando 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 egrepe le awkutilità 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 awkfino alla versione 4.0.0 (2011) non supportava a {meno che non fosse forzato nella modalità di conformità POSIX.
quando GNU grepfu 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 (.)\1in GNU egrep(anche se non è POSIX o supportato da molte altre implementazioni tra cui GNU awk).
L'aggiunta di \xoperatori non è l'unico modo per aggiungere più operatori in modo compatibile con le versioni precedenti. Ad esempio, perlusato (?...). È ancora compatibile con le ERE all'indietro in quanto (?=...)non è valido nelle ERE, lo stesso per .*?. vimper operatori simili ha fatto diversamente introducendo \@=o .\{-}per esempio.