Por que o regex do Vim não permite mais de 9 grupos de captura?

16

A partir :h E65podemos ver que Vim não permite mais de 9 grupos de captura em um comando de substituição.

Por exemplo, o seguinte comando funcionará:

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

Mas este com mais um grupo de captura falhará:

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

Minha pergunta não é sobre por que falha (é um limite rígido do Vim), mas sobre por que o Vim tem esse limite?

Além disso, estou ciente de que uma regex da vida real com mais de 9 grupos de captura provavelmente seria bastante monstruosa de ler e manter, mas ainda estou curioso.

statox
fonte
2
Talvez não esteja relacionado apenas ao Vim: stackoverflow.com/a/10993346/2558252
nobe4
1
@ nobe4: Interessante! Então, talvez as pessoas a criar essas ferramentas consideraram que mais de 9 grupos eram inúteis ...
statox
Suponho que esse limite venha do vi, que herdou o limite do ed / sed. Alguns anos atrás eu fiz um patch para suportar até 99 grupos, mas não foi incluído
Christian Brabandt
1
@ChristianBrabandt Uma adição mais útil seria implementar sinalizadores numéricos como em sed: s/.../.../3substituiria apenas a terceira ocorrência do padrão. Este é provavelmente o recurso que mais sinto falta no Vim.
Sato Katsura
2
O suporte a capturas nomeadas seria outra maneira de aliviar esse problema. Dito isto, na maioria das vezes que vi em qualquer lugar perto de nove grupos de captura, era quando as pessoas não sabiam que poderiam usar grupos que não capturavam - \%().
jamessan

Respostas:

24

A razão óbvia é que os grupos com dois ou mais dígitos são ambíguos: devem \12ser tomados como grupo 12 ou como grupo 1 seguido pela sequência 2?

Existem outros motivos relacionados à eficiência (tempo de correspondência exponencial e similares). Estes foram uma rolha quando edfoi escrito. Algoritmos melhores foram descobertos desde então.

Sato Katsura
fonte
Essa é uma boa possibilidade, você tem alguma referência / leitura sobre isso?
nobe4
2
@ nobe4 Para a parte da ambiguidade: não, mas a IMO é óbvia. Para a parte da eficiência, você precisa ler sobre as implementações iniciais dos regexps. Era um problema bem conhecido na época. Não tenho citações exatas, mas elas não devem ser difíceis de encontrar.
Sato Katsura
Na verdade, isso parece totalmente plausível.
statox
4
Sim, é quase definitivamente que o analisador foi gravado para procurar um único dígito após a barra invertida e nunca mudou. Isso já era bastante comum, há muito tempo. Outros idiomas criaram maneiras de contornar isso (por exemplo, considerando apenas \11uma referência a uma captura se houver pelo menos 11 deles, o que é inconsistente, mas geralmente correto; e coisas como \g{11}para referências anteriores e ${11}substituições), mas o vim nunca introduziu qualquer um desses.
Hbbs 22/09