Почему Vim Regex не позволяет более 9 групп захвата?

16

Из :h E65рисунка видно, что Vim не позволяет использовать более 9 групп захвата в команде замещения.

Например, будет работать следующая команда:

s/\v(a)(b)(c)(d)(e)(f)(g)(h)(i)/\9\8\7\6\5\4\3\2\1

Но этот с еще одной группой захвата потерпит неудачу:

s/\v(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)/\10\9\8\7\6\5\4\3\2\1

Мой вопрос не о том, почему он терпит неудачу (это жесткое ограничение Vim), а о том, почему Vim вообще имеет это ограничение?

Кроме того, я знаю, что реальное регулярное выражение с более чем 9 группами захвата, вероятно, было бы довольно чудовищно для чтения и поддержки, но мне все еще любопытно.

statox
источник
2
Может быть, не относится только к Vim: stackoverflow.com/a/10993346/2558252
nobe4
1
@ nobe4: интересно! Поэтому, возможно, люди, создававшие эти инструменты, считали, что более 9 групп были бесполезны ...
statox
Я полагаю, это ограничение происходит от vi, который унаследовал ограничение от ed / sed. Несколько лет назад я сделал патч для поддержки до 99 групп, но он не был включен
Кристиан Брабандт
1
@ChristianBrabandt Более полезным дополнением будет реализация числовых флагов, таких как sed: s/.../.../3заменяет только 3-е вхождение шаблона. Вероятно, эта функция мне больше всего не хватает в Vim.
Сато Кацура
2
Поддержка именованных захватов будет еще одним способом облегчить эту проблему. При этом в большинстве случаев я видел где-то около 9 групп захвата, когда люди не знали, что могут использовать группы без захвата \%().
Jamessan

Ответы:

24

Очевидная причина заключается в том, что группы с двумя или более цифрами неоднозначны: следует \12принимать за группу 12 или за группу 1, за которой следует строка 2?

Существуют и другие причины, связанные с эффективностью (экспоненциальное время согласования и т. П.). Это были шоу-пробки, когда edбыло написано. Лучшие алгоритмы были открыты с тех пор.

Сато Кацура
источник
Это хорошая возможность, есть ли у вас какие-либо ссылки / чтения по этому поводу?
nobe4
2
@ nobe4 Для двусмысленности: нет, но IMO это очевидно. Что касается эффективности, вам нужно прочитать о ранних реализациях регулярных выражений. Это была хорошо известная проблема в то время. У меня нет точных ссылок, но их не должно быть трудно найти.
Сато Кацура
Действительно, это звучит вполне правдоподобно.
statox
4
Да, почти наверняка синтаксический анализатор был написан для поиска одной цифры после обратной косой черты и никогда не менялся. Это было достаточно распространенным, давно. Другие языки нашли способы обойти это (например, рассматривая \11ссылку на перехват, только если их хотя бы 11, что противоречиво, но обычно нормально; и такие вещи, как \g{11}обратные ссылки и ${11}замены), но vim никогда представил любой из тех.
Хоббс