REGXY, 53 49 bytes
Utiliza REGXY , un lenguaje basado en la sustitución de expresiones regulares.
//$'#/
/.(.+)#\1\K/#/
a/(#).(.*#)|#.*/$'$1$2/
//a
Descripción general:
se aplican varias expresiones regulares. Un ejemplo de ejecución se vería así:
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 #)
Explicación detallada
El siguiente es un desglose línea por línea de las expresiones regulares:
//$'#/
Esta es una sustitución de expresiones regulares que coincide con la primera cadena vacía (es decir, el inicio de la cadena) y la reemplaza con todo a la derecha de la coincidencia ( $'
) seguido de un hash. Por ejemplo, se convertirá onion
enonion#onion
.
/.(.+)#\1\K/#/
Esta línea encuentra la sección que se superpone al buscar un grupo de caracteres que preceden inmediatamente al # ( (.+)
) que son los mismos en el otro lado del # ( \1
). El \ K simplemente significa 'olvida que hice coincidir cualquier cosa', lo que significa que en realidad no será reemplazado en la sustitución. Esto efectivamente, esto significa que simplemente agregamos un # a la posición después de que se haya encontrado la superposición, convirtiéndose onion#onion
en onion#on#ion
.
a/(#).(.*#)|#.*/$'$1$2/
La 'a' inicial es solo una etiqueta para la expresión regular. Después de esto, encontramos el primer # seguido de un solo carácter ( .
) y capturamos todo después de esto hasta el siguiente # ( .*#
). Reemplazamos esto con todo a la derecha del partido, es decir, el último token ($ '), seguido de un # ( $1
), seguido del segundo token menos un carácter (tratamos esto como un contador, disminuyéndolo en cada iteración). En el caso de la cebolla # en # ion, las dos fichas a las que hacemos referencia se muestran entre paréntesis, y la sección que coincide con la expresión regular completa se encuentra entre las tuberías:onion|(#)o(n#)|ion
. Luego reemplazamos los bits que emparejamos (entre las tuberías) con $'
(todo a la derecha del emparejamiento, es decir, 'ion'), luego $ 1 (el #), luego $ 2 (n #), lo que significa que terminamos con onion|(ion)(#)(n#)|ion
(los paréntesis muestran los tres tokens en la cadena de reemplazo).
Si la expresión regular no coincide en la primera alternancia (todo antes de la tubería), debemos haber reducido nuestro contador a cero, lo que significa que no hay caracteres dentro de la segunda ficha. En su lugar, nos fijamos en la segunda parte del patrón, #.*
. Esto simplemente reemplaza todo después del primer # con $'$1$2
. Dado que esta alternancia no crea referencias inversas, y no hay nada a la derecha de la coincidencia ( .*
coincide hasta el final de la cadena), terminamos la coincidencia y devolvemos el resultado.
//a
Esto es solo un puntero a la línea anterior, lo que garantiza que continuaremos ejecutando la sustitución de expresiones regulares hasta que ya no coincida.