C'est pour des raisons historiques.
Regexp a été introduit pour la première fois dans Unix dans l' ed
utilitaire au début des années 70. Bien que ed
se fondait sur qed
dont la mise en œuvre par les mêmes auteurs compris regexp plus complexe, ed
ne comprenait ^
, $
, [...]
, .
, *
et \
d'échapper à tout ce qui précède.
Désormais, lorsque le besoin d'avoir plus d'opérateurs s'est fait sentir, il fallait trouver un moyen de les introduire sans rompre la compatibilité descendante. Si un script utilisait la s
ed
commande as s/foo() {/foo (var) {/g
pour remplacer toutes les instances de foo() {
with foo(var) {
et que vous introduisiez un opérateur (
or {
, cela casserait ce script.
Cependant, aucun script ne ferait l'affaire s/foo\(\) {/foo\(var\) {/
, car c'est la même chose s/foo() {/foo(var) {/
et il n'y avait aucune raison de s'échapper (
car il ne s'agissait pas d'un opérateur RE. Ainsi, l'introduction d'un nouvel opérateur \(
ou \{
n'interrompt pas la compatibilité descendante car il est très peu probable qu'il casse un script existant en utilisant l'ancienne syntaxe.
C'est donc ce qui a été fait. Plus tard, a \(...\)
été ajouté initialement uniquement pour que la s
ed
commande fasse des choses comme s/foo\(.\)/\1bar/
et plus tard grep '\(.\)\1'
(mais pas des choses comme \(xx\)*
).
Dans UnixV7 (1979, donc près d'une décennie plus tard), une nouvelle forme d'expressions régulières a été ajoutée dans le nouveau egrep
et les awk
utilitaires appelés expression régulière étendue (car ce sont de nouveaux outils, il n'y a pas de compatibilité descendante à rompre). Enfin, il a fourni les fonctionnalités disponibles dans l'ancien de Ken Thompson qed
(opérateur d'alternance |
, regroupement (..)*
) et a ajouté quelques opérateurs comme +
et ?
(mais n'avait pas la fonction backref des expressions régulières de base).
Plus tard, les BSD ont ajouté \<
et \>
(à la fois à BRE et à ERE), et SysV a ajouté \{
et \}
à BRE uniquement.
Ce n'est que bien plus tard que {
et }
ont été ajoutés à ERE, par une telle compatibilité descendante. Tout le monde ne l'a pas ajouté. Par exemple, GNU awk
jusqu'à la version 4.0.0 (2011) ne prenait pas en charge à {
moins d'être forcé en mode de conformité POSIX.
quand GNU a grep
été écrit au début des années 90, il a ajouté tous les goodies de BSD et SysV (comme \<
, {
) et au lieu d'avoir deux syntaxe regexp et moteur distincts pour BRE et ERE, a implémenté les mêmes opérateurs dans les deux, seuls les homologues BRE de (
, ?
, {
, +
doivent être précédés d'une barre oblique inverse (pour être compatible avec d' autres implémentations BRE). C'est pourquoi vous pouvez le faire .\+
dans GNU grep
(bien que ce ne soit pas POSIX ou pris en charge par d'autres implémentations) et vous pouvez le faire (.)\1
dans GNU egrep
(bien que ce ne soit pas POSIX ou pris en charge par de nombreuses autres implémentations, y compris GNU awk
).
L'ajout d' \x
opérateurs n'est pas le seul moyen d'ajouter plus d'opérateurs d'une manière rétrocompatible. Par exemple, perl
utilisé (?...)
. C'est toujours rétrocompatible avec les ERE car il (?=...)
n'est pas valide dans les ERE, de même pour .*?
. vim
pour des opérateurs similaires l'ont fait différemment en introduisant \@=
ou .\{-}
par exemple.