Это по историческим причинам.
Regexp были впервые представлены в Unix в ed
утилите в начале 70-х годов. Хотя ed
был основан на qed
осуществление которых по тем же авторов понимается более сложное регулярное выражение, ed
только понял ^
, $
, [...]
, .
, *
и , \
чтобы избежать всего вышеперечисленного.
Теперь, когда возникла необходимость иметь больше операторов, нужно было найти способ представить их без нарушения обратной совместимости. Если скрипт , используемый , чтобы использовать s
ed
команду , как s/foo() {/foo (var) {/g
заменить все экземпляры foo() {
с , foo(var) {
и вы ввели (
или {
оператора, что бы разорвать этот сценарий.
Однако ни один скрипт не подойдет s/foo\(\) {/foo\(var\) {/
, потому что это так же, как s/foo() {/foo(var) {/
и не было никаких причин сбегать, (
поскольку это не оператор RE. Таким образом, введение нового оператора \(
или \{
оператора не нарушает обратную совместимость, поскольку очень маловероятно, что существующий сценарий нарушит старый синтаксис.
Итак, вот что было сделано. Позже, \(...\)
был добавлен изначально только для s
ed
команды, чтобы сделать что-то вроде, s/foo\(.\)/\1bar/
а позже как grep '\(.\)\1'
(но не так, как \(xx\)*
).
В UnixV7 (1979 год, то есть почти десятилетие спустя) в новую и регулярные выражения были добавлены новая форма регулярных выражений egrep
и awk
утилиты, называемые расширенными регулярными выражениями (поскольку они являются новыми инструментами, обратной совместимости нарушать нельзя). Наконец, он предоставил функциональность, доступную в древнем Кене Томпсоне qed
(оператор чередования |
, группировка (..)*
), и добавил несколько операторов, таких как +
и ?
(но не имел функции обратной ссылки в основных регулярных выражениях).
Позже BSD добавили \<
и \>
(и к BRE, и к ERE), а SysV добавили \{
и \}
только к BRE.
Это не намного позже {
и }
были добавлены в ERE, из-за такой нарушения обратной совместимости. Не все это добавили. Например, GNU awk
до версии 4.0.0 (2011) не поддерживала, {
пока не была переведена в режим соответствия POSIX.
когда GNU grep
был написан в начале 90-х, он добавил все вкусности от BSD и SysV (вроде \<
, {
), и вместо того, чтобы иметь два отдельных синтаксиса regexp и механизм для BRE и ERE, реализовал одинаковые операторы в обоих, только аналоги BRE (
, ?
, {
, +
должны предшествовать с обратной косой черты (чтобы быть совместимым с другими реализациями BRE). Вот почему вы можете делать это .\+
в GNU grep
(хотя это не POSIX или не поддерживается другими реализациями), и вы можете делать это (.)\1
в GNU egrep
(хотя это не POSIX или не поддерживается многими другими реализациями, включая GNU awk
).
Добавление \x
операторов - не единственный способ добавить больше операторов в обратно совместимом виде. Например, perl
используется (?...)
. Это все еще обратно совместимо с ERE, что (?=...)
недопустимо в ERE, то же самое для .*?
. vim
для аналогичных операторов сделал это по-другому, введя \@=
или, .\{-}
например.