REGXY, 53 49 bajtów
Używa REGXY , języka opartego na podstawieniu wyrażenia regularnego
//$'#/
/.(.+)#\1\K/#/
a/(#).(.*#)|#.*/$'$1$2/
//a
Omówienie:
zastosowano wiele wyrażeń regularnych. Przykładowy przebieg wyglądałby następująco:
onion (input)
onion#onion (line 1 regex)
onion#on#ion (line 2 regex - find the repeated section and separate with #)
onionion#n#ion (line 3 regex - the length of the middle token is the garland order, remove a character and append the third token onto the original string on the left)
onionionion##ion (line 4 regex is a pointer to line 3 - repeat the previous again)
onionionion##ion (line 4 regex is a pointer to line 3 - strip everything after and including the #)
Szczegółowe wyjaśnienie
Poniżej przedstawiono podział wyrażeń regularnych według wierszy:
//$'#/
Jest to podstawienie wyrażenia regularnego, które dopasowuje pierwszy pusty ciąg (tj. Początek łańcucha) i zastępuje go wszystkim po prawej stronie match ( $'
), po którym następuje skrót. Na przykład zamieni się onion
w onion#onion
.
/.(.+)#\1\K/#/
Ta linia znajduje sekcję, która zachodzi na siebie, szukając grupy znaków bezpośrednio poprzedzających # ( (.+)
), które są takie same po drugiej stronie # ( \1
). \ K oznacza po prostu „zapomnij, że coś dopasowałem”, co oznacza, że tak naprawdę nie zostanie zastąpione przez podstawienie. W efekcie oznacza to, że po znalezieniu nakładki dodajemy # do pozycji, zamieniając się onion#onion
w onion#on#ion
.
a/(#).(.*#)|#.*/$'$1$2/
Początkowe „a” jest tylko etykietą wyrażenia regularnego. Następnie znajdujemy pierwszy #, a następnie pojedynczy znak ( .
) i przechwytujemy wszystko do następnego # ( .*#
). Zastępujemy to wszystkim po prawej stronie dopasowania, tj. Ostatnim tokenem ($ '), a następnie znakiem # ( $1
), a następnie drugim tokenem bez znaku (traktujemy to jako licznik, zmniejszając go z każdą iteracją). W przypadku cebuli # na # jonów, dwa żetony na my wsteczne są pokazane w nawiasach, a sekcja całe mecze regex jest między rurami: onion|(#)o(n#)|ion
. Następnie zamieniamy pasujące bity (między rurami) na $'
(wszystko po prawej stronie dopasowania, tj. „Jon”), następnie 1 $ (the #), a następnie 2 $ (n #), co oznacza, że otrzymujemy onion|(ion)(#)(n#)|ion
(nawiasy kwadratowe pokazują trzy tokeny w ciągu zastępującym).
Jeśli wyrażenie regularne nie pasuje do pierwszej alternacji (wszystko przed potokiem), musimy zmniejszyć nasz licznik do zera, co oznacza, że w drugim tokenie nie ma żadnych znaków. Zamiast tego, możemy spojrzeć na drugą część wzoru, #.*
. To po prostu zastępuje wszystko po pierwszym # $'$1$2
. Ponieważ nie ma żadnych odwołań wstecznych utworzonych przez tę alternatywę, a po prawej stronie dopasowania nie ma nic ( .*
dopasowania do końca łańcucha), kończymy dopasowanie i zwracamy wynik.
//a
Jest to tylko wskaźnik do poprzedniej linii, zapewniający kontynuowanie podstawiania wyrażenia regularnego, dopóki nie będzie już pasować.