- Cuando necesitas comparar expresiones regulares como si fueran conjuntos de cadenas, antimirov calcula en una sola pantalla la inclusión y equivalencia entre dos expresiones α y β, además de su intersección y diferencia
- El área de resultados muestra el complemento y las relaciones al mismo tiempo, y permite revisar operaciones como
~α,α < β,α = β,α & β,α ^ β,α - β - Si ingresas una cadena aparte s, puedes verificar de inmediato si coincide con cada expresión regular mediante
s ∈ α,s ∈ β - La sintaxis soporta
., concatenación, alternancia|, repetición*·+·?·{n}·{m,n}, grupos de caracteres, grupos de caracteres negados, escapes y escapes Unicode UTF-16 - No soporta funciones que cambian el comportamiento como anclas, aserciones de longitud cero, retroreferencias, extracción de subgrupos, búsqueda o coincidencia parcial, ni ignorar mayúsculas/minúsculas
Comparación de expresiones regulares y operaciones de conjuntos
- El área de entrada recibe dos expresiones regulares α y β
- La salida muestra conjuntamente el complemento y las operaciones relacionales y de conjuntos entre ambas expresiones regulares
~α,~β: complemento de cada expresión regularα < β,α = β,α > β: relación de inclusión y equivalencia entre las dos expresiones regularesα & β: intersecciónα ^ β: diferencia simétricaα - β: diferencia
- Si ingresas la cadena s, puedes comprobar si pertenece a cada expresión regular en la forma
s ∈ α,s ∈ β - También se muestra el tamaño de cada expresión regular y la cantidad de estados del DFA
- En la pantalla de ejemplo,
|α| = 1,|β| = 1 - En la pantalla de ejemplo,
dfa(α)ydfa(β)tienen 1 estado cada uno
- En la pantalla de ejemplo,
Sintaxis de expresiones regulares compatible
- Los operadores básicos cubren carácter único, concatenación, alternancia y repetición
.: coincide con cualquier carácter únicoxy: concatenación que coincide conxseguido deyx|y: coincide conxoyx*: repetición de 0 o más veces(xyz): agrupación(): expresión regular vacía que coincide con la cadena vacía
- También soporta abreviaturas comunes de repetición
x+: repetición de 1 o más veces, equivalente axx*x?: coincidencia opcional, equivalente a(x|)x{n}: concatenaxn vecesx{m,n}: concatenaxentre m y n veces
- Los conjuntos de caracteres y escapes pueden usarse en las siguientes formas
[a-z0-9]: coincide con un carácter único dentro del grupo[^a-z0-9]: coincide con un carácter único que no está en el grupo\c: escape del carácter especialc\u001a: coincide con el carácter UTF-16 correspondiente- Además, caracteres como
a,b,ccoinciden consigo mismos
Funciones no compatibles
- antimirov se enfoca en tratar las expresiones regulares como objetos de operaciones de conjuntos, por lo que excluye las siguientes funciones
- Anclas
^,$- Aun así,
^y$deben escaparse
- Aun así,
- Aserciones de longitud cero, por ejemplo
(?=...),(?<=...) - Retroreferencias, por ejemplo
\1,\2 - Extracción de subgrupos
- Búsqueda o coincidencia parcial
- Otras banderas que cambian el comportamiento, como ignorar mayúsculas/minúsculas
- Anclas
- Puedes consultar más información en non/antimirov
1 comentarios
Comentarios de Hacker News
Hice una demo web similar que muestra cómo una expresión regular se transforma en parsing → NFA → DFA → DFA mínimo, y luego genera salida hasta LLVM IR/Javascript/WebAssembly
http://compiler.org/reason-re-nfa/src/index.html
Como referencia, la derivada de Brzozowski también puede ser interesante como enfoque alternativo para hacer matching de expresiones regulares: https://en.wikipedia.org/wiki/Brzozowski_derivative
Esta biblioteca puede usarse para construir una jerarquía de clases de strings, y como resultado aprovechar de forma más agresiva los strings tipados
Por ejemplo, el email y la URL tienen una gramática especial, y su espacio de valores es un subconjunto de todos los strings no vacíos; a su vez, los strings no vacíos son un subconjunto de todos los strings
Si el sistema de tipos sabe que un string de email es un subtipo de string no vacío, puede considerar válido pasar una dirección de email a una función que requiere un string no vacío
Esta biblioteca puede usarse para verificar la definición y la jerarquía de esos tipos de string, y la implementación de la jerarquía cambia según el lenguaje, ya sea con subclases, límites de traits, etc.
No se exporta el constructor
Address, solo el tipo, y se valida dentro defromString :: Text -> Maybe Address; si la dirección no es válida, devuelveNothingLa validez no se mezcla dentro de los datos, sino que se señala por una vía aparte, y cuando hace falta mostrarla se vuelve a extraer el valor envuelto con
toText :: Address -> Texthttps://news.ycombinator.com/item?id=31092912
@en una dirección de emailLa heurística simple de asumir que toda expresión regular que intente representar una “dirección de email válida” está equivocada es bastante segura, pero le quita toda la diversión
Las expresiones regulares son un gran ejemplo de cómo una teoría matemática bastante elegante y compleja puede empaquetarse en una interfaz valiosa
El álgebra lineal me produce una sensación parecida
Incluso una transformación de Möbius del plano complejo
w=(az+b)/(cz+d)puede convertirse en álgebra linealLas buenas interfaces tienen un valor esencial, aunque mucha gente orientada solo a resultados no lo reconozca bien
Esta página genial calcula la relación binaria entre pares de expresiones regulares y muestra el DFA como grafo
Hace una demostración realmente impresionante de operaciones bastante no triviales sobre expresiones regulares
Aun así, pensé que los anchors
^y$no iban a ser problemaPegué “regex filter numbers divisible by 3” y la página se quedó completamente congelada: https://stackoverflow.com/q/10992279/41948
^(?:[0369]+|[147](?:[0369]*[147][0369]*[258])*(?:[0369]*[258]|[0369]*[147][0369]*[147])|[258](?:[0369]*[258][0369]*[147])*(?:[0369]*[147]|[0369]*[258][0369]*[258]))+$^([0369]|[147][0369]*[258]|(([258]|[147][0369]*[147])([0369]|[258][0369]*[147])*([147]|[258][0369]\*[258])))+$Me pregunto si habrá una expresión más corta
Por ejemplo
(ab+c+)+,(abc){100},a.*quick brown fox jumps over the lazy dogQuería ver la intersección entre URLs y direcciones de email gramaticalmente válidas, pero incluso ingresando solo la regex de URL de abajo la página tarda demasiado en procesarla
[\-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([\-a-zA-Z0-9()@:%_+.~#?&//=]*)Fuente: https://stackoverflow.com/a/3809435/623763
(...){1,256}son muy pesadas, y el código Scala JS termina agotando el tiempo o matando el navegadorSi lo cambias por
(...)+, al menos en mi entorno funciona. Expresiones pequeñas como(...){1,6}probablemente estén bienAl principio me sorprendió y luego me hizo sentido que las expresiones regulares generadas por unión e intersección no sean especialmente compactas
Por ejemplo, la intersección de
"y.+"y".+z"puede escribirse con una expresión muy simple:"y.*z", y la página también confirma la equivalencia. Pero la herramienta devuelveyz([^z][^z]*z|z)*|y[^z](zz*[^z]|[^z])*zz*Debe haber una razón para que salga así, pero producir una expresión regular mínima según criterios como cantidad de caracteres probablemente sea mucho más difícil
".+z"se vuelve más grande y desordenada después de convertirse en un autómata deterministaHace tiempo usé este concepto para escribir la lógica de validación de una configuración de “IP RegEx filter”
La meta era permitir que el usuario configurara el filtro de IP con una expresión regular. El equipo de marketing no entendía CIDR, pero sí conocía las expresiones regulares por Google Analytics
¿Cómo se puede definir una expresión regular válida? La intersección con la expresión regular de “todas las direcciones IPv4” no debía estar vacía y, al mismo tiempo, tampoco debía ser igual a la expresión regular de “todas las direcciones IPv4”
Esto evitó muchas quejas de que el filtro no hacía nada, pero no impidió que se ingresaran filtros incorrectos
También ayudaría a tratar el problema de los filtros incorrectos
Para que fuera más cómodo de usar en móvil, sería bueno desactivar las sugerencias automáticas en el campo de entrada de expresiones regulares
https://stackoverflow.com/questions/35513968/disable-autocor...
Probé la página con 2 expresiones regulares de números divisibles entre 3 similares, y se colgaba incluso si quitaba los
^y$de los extremosRegex 1:
([0369]|([258]|[147][0369]*[147])([0369]|([147][0369]*[258]|[258][0369]*[147]))*([147]|[258][0369]*[258])|([147]|[258][0369]*[258])([0369]|([147][0369]*[258]|[258][0369]*[147]))*([258]|[147][0369]*[147]))*Regex 2:
([0369]|[258][0369]*[147]|(([147]|[258][0369]*[258])([0369]|[147][0369]*[258])*([258]|[147][0369]*[147])))*Todo se parsea hasta justo antes del último
*, pero en cuanto se agrega ese*, toda la página se congelaSin ese
*, se obtuvo un validador válido que parsea fragmentos numéricos cuya suma de dígitos es divisible entre 3