Dlaczego Vim regex nie pozwala na więcej niż 9 grup przechwytywania?

16

Od :h E65widzimy, że Vim nie pozwala na więcej niż 9 grup przechwytywania w poleceniu substytucyjnego.

Na przykład zadziała następujące polecenie:

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

Ale ta z jeszcze jedną grupą przechwytywania zawiedzie:

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

Moje pytanie nie dotyczy tego, dlaczego zawodzi (jest to twardy limit Vima), ale dlaczego w ogóle Vim ma ten limit?

Wiem też, że regex z więcej niż 9 grup przechwytywania byłby prawdopodobnie potworny do przeczytania i utrzymania, ale nadal jestem ciekawy.

statox
źródło
2
Może nie związany tylko z Vimem: stackoverflow.com/a/10993346/2558252
nobe4
1
@ nobe4: Ciekawe! Może więc ludzie tworzący te narzędzia uważają, że ponad 9 grup było bezużytecznych ...
statox
Przypuszczam, że ten limit pochodzi od vi, który odziedziczył limit po ed / sed. Kilka lat temu zrobiłem łatkę obsługującą do 99 grup, ale nie została uwzględniona
Christian Brabandt
1
@ChristianBrabandt Bardziej użytecznym dodatkiem byłoby zaimplementowanie flag numerycznych jak w sed: s/.../.../3zastąpiłoby tylko 3. wystąpienie wzorca. Jest to prawdopodobnie funkcja, za którą najbardziej tęsknię w Vimie.
Sato Katsura
2
Obsługa nazwanych przechwyceń byłaby innym sposobem na złagodzenie tego problemu. To powiedziawszy, większość razy widziałem w pobliżu 9 grup przechwytywania, kiedy ludzie nie wiedzieli, że mogą używać grup nie przechwytujących - \%().
jamessan

Odpowiedzi:

24

Oczywistym powodem jest to, że grupy z dwiema lub więcej cyframi są niejednoznaczne: czy należy \12je traktować jako grupę 12, czy jako grupę 1, po której następuje łańcuch 2?

Istnieją inne powody związane z wydajnością (wykładniczy czas dopasowania i tym podobne). Były one przystankiem koncertowym, kiedy edzostało napisane. Od tego czasu odkryto lepsze algorytmy.

Sato Katsura
źródło
To dobra możliwość, czy masz jakieś referencje / lektury na ten temat?
nobe4
2
@ nobe4 Dla części dwuznaczności: nie, ale IMO jest oczywiste. W części dotyczącej wydajności należy przeczytać o wczesnych implementacjach wyrażeń regularnych. Był to wówczas znany problem. Nie mam dokładnych cytatów, ale nie powinny być trudne do znalezienia.
Sato Katsura
Rzeczywiście, brzmi to całkowicie prawdopodobne.
statox
4
Tak, to prawie na pewno, że parser został napisany, aby szukać pojedynczej cyfry po odwrotnym ukośniku i nigdy się nie zmienił. To było dość powszechne, dawno temu. Inne języki wymyśliły sposoby na obejście tego (na przykład, biorąc pod uwagę \11odniesienie do przechwytywania, jeśli jest ich co najmniej 11, co jest niespójne, ale zwykle w porządku; i takie rzeczy, jak \g{11}odniesienia do referencji i ${11}zastępowania), ale vim nigdy nie wprowadził którykolwiek z nich.
hobbs