!rm`.*$
Z jednym wyrażeniem regularnym Retina działa w trybie dopasowania. Zwykle drukuje to tylko liczbę dopasowań, ale !
konfigurujemy go tak, aby zamiast tego wyświetlał rzeczywiste dopasowania (oddzielone liniami).
Rzeczywiste wyrażenie regularne jest tylko .*$
. .*
dopasowuje dowolną linię (potencjalnie pustą), ponieważ .
może pasować do dowolnego znaku oprócz linii. Dotrę $
za chwilę.
Jak sprawić, by wydrukował mecze w odwrotnej kolejności? Korzystając z trybu dopasowywania od prawej do lewej platformy .NET, aktywowanego za pomocą r
. Oznacza to, że silnik wyrażeń regularnych uruchamia się na końcu łańcucha podczas wyszukiwania dopasowań i działa wstecz.
Wreszcie, m
sprawia, że $
dopasowanie jest końcem linii zamiast końca łańcucha. Dlaczego tego potrzebujemy? Problem polega na tym, że .*
generuje obce dopasowania. Rozważ podstawienie wyrażenia regularnego
s/a*/$0x/
zastosowane do danych wejściowych baaababaa
. Można by pomyśleć, że to przyniesie baaaxbaxbaax
, ale tak naprawdę daje baaaxxbaxxbaaxx
. Czemu? Ponieważ po dopasowaniu aaa
kursor silnika znajduje się między a
a b
. Teraz nie może dopasować więcej a
s, ale a*
jest również zadowolony z pustego ciągu. Oznacza to, że po każdym pojedynczym meczu otrzymujesz kolejny pusty mecz.
Nie chcemy tego tutaj, ponieważ wprowadziłoby to dodatkowe puste linie, dlatego odrzucamy te obce dopasowania (które są na początku linii ze względu na tryb od prawej do lewej), wymagając, aby dopasowania zawierały koniec linia.
tac
jest trochę dziwne, jeśli chodzi o końcowe linie. Przekształcaa\nb\n
(trailing linefeed) wb\na\n
ia\nb
(bez trailing linefeed) wba\n
. Czy tak ma zachowywać się nasz kod?