To z powodów historycznych.
Regexp został po raz pierwszy wprowadzony w Uniksie w ed
użyteczności na początku lat 70. Choć ed
była oparta na qed
którego realizacja przez tych samych autorów rozumieć bardziej złożone wyrażenia regularnego, ed
tylko rozumieć ^
, $
, [...]
, .
, *
i \
aby uniknąć wszystkich wyżej wymienionych.
Teraz, gdy pojawiła się potrzeba posiadania większej liczby operatorów, trzeba było znaleźć sposób na wprowadzenie ich bez naruszania wstecznej kompatybilności. Jeśli skrypt użył s
ed
polecenia s/foo() {/foo (var) {/g
do zastąpienia wszystkich instancji słowem „ foo() {
a” foo(var) {
i wprowadzono operator (
lub {
, spowoduje to uszkodzenie tego skryptu.
Jednak żaden skrypt nie zrobiłby tego s/foo\(\) {/foo\(var\) {/
, ponieważ jest to to samo, co s/foo() {/foo(var) {/
nie było powodu do ucieczki, (
ponieważ nie był to operator RE. Tak więc wprowadzenie nowego \(
lub \{
operatora nie psuje kompatybilności wstecznej, ponieważ bardzo mało prawdopodobne jest uszkodzenie istniejącego skryptu przy użyciu starszej składni.
Tak właśnie zostało zrobione. Później \(...\)
dodano początkowo tylko dla s
ed
polecenia, aby robić rzeczy takie jak s/foo\(.\)/\1bar/
i później jako grep '\(.\)\1'
(ale nie takie rzeczy jak \(xx\)*
).
W UnixV7 (1979, a więc prawie dekadę później) dodano nową formę wyrażeń regularnych w nowym narzędziu egrep
i awk
narzędzia zwane rozszerzonym wyrażeniem regularnym (ponieważ są to nowe narzędzia, nie ma zgodności wstecznej do złamania). Wreszcie zapewnił funkcjonalność dostępną w starożytnej wersji Kena Thompsona qed
(operator przemiany |
, grupowanie (..)*
) i dodał kilka operatorów takich jak +
i ?
(ale nie posiadał funkcji wstecznego wyrażenia podstawowych wyrażeń regularnych).
Później dodano BSD \<
i \>
(zarówno do BRE, jak i ERE), a SysV dodano \{
i \}
tylko do BRE.
Dopiero znacznie później {
i }
zostały dodane do ERE przez takie łamanie wstecznej kompatybilności. Nie wszyscy to dodali. Na przykład GNU awk
do wersji 4.0.0 (2011) nie obsługiwał, {
chyba że został zmuszony do trybu zgodności z POSIX.
kiedy GNU grep
zostało napisane na początku lat 90., dodało wszystkie zalety zarówno BSD, jak i SysV (jak \<
, {
) i zamiast mieć dwie osobne składnie wyrażeń regularnych i silnik dla BRE i ERE, zaimplementowało te same operatory w obu, tylko odpowiedniki BRE z (
, ?
, {
, +
muszą być poprzedzone odwrotnym ukośnikiem (być kompatybilny z innymi implementacjami BRE). Dlatego możesz to zrobić .\+
w GNU grep
(chociaż nie jest to POSIX lub nie jest obsługiwane przez inne implementacje) i możesz to zrobić (.)\1
w GNU egrep
(choć nie jest to POSIX ani obsługiwane przez wiele innych implementacji, w tym GNU awk
).
Dodawanie \x
operatorów nie jest jedynym sposobem na dodanie większej liczby operatorów w sposób kompatybilny wstecz. Na przykład perl
używane (?...)
. Jest to nadal kompatybilne wstecz z ERE, ponieważ (?=...)
nie jest ważne w ERE, to samo dla .*?
. vim
dla podobnych operatorów zrobili to inaczej wprowadzając \@=
lub .\{-}
na przykład.