Introducción
No veo muchos desafíos de expresiones regulares aquí, por lo que me gustaría ofrecer este engañosamente simple que se puede hacer de varias maneras usando una serie de sabores de expresiones regulares. Espero que les brinde a los entusiastas de las expresiones regulares un poco de tiempo de golf divertido.
Desafío
El desafío es hacer coincidir lo que he denominado muy libremente una serie "igualitaria": una serie de números iguales de diferentes personajes. Esto se describe mejor con ejemplos.
Partido:
aaabbbccc
xyz
iillppddff
ggggggoooooollllllffffff
abc
banana
No coinciden:
aabc
xxxyyzzz
iilllpppddff
ggggggoooooollllllfff
aaaaaabbbccc
aaabbbc
abbaa
aabbbc
Generalizar, que queremos para que coincida con un tema de la forma ( para cualquier lista de los caracteres a , donde para todosc1)n(c2)n(c3)n...(ck)n
c1
ck
ci != ci+1
i, k > 1, and n > 0.
Aclaraciones:
La entrada no estará vacía.
Un carácter puede repetirse más tarde en la cadena (por ejemplo, "banana")
k > 1
, por lo que siempre habrá al menos 2 caracteres diferentes en la cadena.Puede suponer que solo se pasarán caracteres ASCII como entrada y ningún carácter será un terminador de línea.
Reglas
(Gracias a Martin Ender por este excelente bloque de reglas)
Su respuesta debe consistir en una única expresión regular, sin ningún código adicional (excepto, opcionalmente, una lista de modificadores de expresión regular necesarios para que su solución funcione). No debe usar las características de la expresión regular de su idioma que le permiten invocar código en el idioma de alojamiento (por ejemplo, el e
modificador de Perl ).
Puede usar cualquier sabor regex que existiera antes de este desafío, pero especifique el sabor.
No asuma que la expresión regular está anclada implícitamente, por ejemplo, si está utilizando Python, suponga que su expresión regular se usa con re.search y no con re.match. Su expresión regular debe coincidir con la cadena completa para cadenas igualitarias válidas y no producir coincidencias para cadenas no válidas. Puede usar tantos grupos de captura como desee.
Puede suponer que la entrada siempre será una cadena de dos o más caracteres ASCII que no contienen terminadores de línea.
Esto es regex golf, por lo que gana la expresión regular más corta en bytes. Si su lenguaje requiere delimitadores (generalmente /.../
) para denotar expresiones regulares, no cuente los delimitadores. Si su solución requiere modificadores, agregue un byte por modificador.
Criterios
Este es un buen golf antiguo, así que olvídate de la eficiencia y solo trata de que tu expresión regular sea lo más pequeña posible.
Mencione qué sabor regex ha utilizado y, si es posible, incluya un enlace que muestre una demostración en línea de su expresión en acción.
fuente
banana
es igualitario.Respuestas:
Sabor .NET, 48 bytes
Pruébalo en línea! (usando Retina )
Bueno, resulta que no negar la lógica es más simple después de todo. Estoy respondiendo esto por separado, porque los dos enfoques son completamente diferentes.
Explicación
fuente
((^.|\2(?=.*\4\3)|\4(?!\3))(?=\2*+((.)\3?)))+\3$
estaba experimentando\3*
en lugar de(?!\3)
hacerlo 45b pero eso falla en "aabbbc" :( La versión de Perl es más fácil de entender, y ahora se reduce a 45b:^((?=(.)\2*(.))(?=(\2(?4)?\3)(?!\3))\2+)+\3+$
- la razón por la que lo llamo Perl a pesar de que parece ser válida PCRE PCRE es que piensa que(\2(?4)?\3)
podría recursivo indefinidamente mientras que Perl es un poco más inteligente / perdona!Sabor .NET, 54 bytes
Pruébalo en línea! (usando Retina )
Estoy bastante seguro de que esto es subóptimo, pero es lo mejor que se me ocurre para equilibrar grupos en este momento. Tengo una alternativa con el mismo número de bytes, que es casi la misma:
Explicación
La idea principal es invertir el problema, unir cadenas no igualitarias y poner todo el asunto en una perspectiva negativa para negar el resultado. El beneficio es que no tenemos que hacer un seguimiento de n a lo largo de toda la cadena (porque debido a la naturaleza de los grupos de equilibrio, generalmente consumes n al verificarlo), para verificar que todas las ejecuciones tengan la misma longitud. En cambio, solo buscamos un solo par de carreras adyacentes que no tengan la misma longitud. De esa manera, solo necesito usar n una vez.
Aquí hay un desglose de la expresión regular.
fuente
banana
,aba
,bbbaaannnaaannnaaa
,bbbaaannnaaannnaaaaaa
,The Nineteenth Byte
,11
,110
,^(?!.*(?<=(\2)*(.))(?!\2)(?>(.)(?<-1>\3)*)(?(1)|\3)).+
,bababa
. Soy yo quien falló. :( +1