regex - probar - Compilador de expresiones regulares
probar expresiones regulares (13)
He tenido la necesidad de usar expresiones regulares solo unas pocas veces en el trabajo que he hecho. Sin embargo, en esas pocas ocasiones descubrí una forma de expresión muy poderosa que me permitiría hacer algunas cosas extremadamente útiles.
El problema es que el lenguaje utilizado para las expresiones regulares es incorrecto, punto final.
Está mal desde un punto de vista psicológico: el uso de símbolos desencarnados proporciona una referencia útil solo para aquellos con una memoria eidética. Si bien las reglas sintácticas están claramente establecidas, según mi experiencia y lo que he aprendido de otros, desarrollar una expresión regular que funcione con éxito puede resultar una tarea difícil en todas las situaciones menos en las más triviales. Esto es comprensible ya que es un análogo simbólico para la teoría de conjuntos, lo cual es bastante complicado.
Una de las cosas que puede resultar difícil es disolver la expresión en la que está trabajando en sus partes discretas. Debido a la naturaleza del lenguaje, es posible leer una expresión regular de múltiples maneras si no comprende su objetivo principal, por lo que es complicado interpretar las expresiones regulares de otras personas. En el estudio del lenguaje natural, creo que esto se llama pragmática.
La pregunta que me gustaría hacer es: ¿existe algo así como un compilador de expresiones regulares? ¿O se puede incluso construir?
Podría ser posible considerar expresiones geográficas, desde un punto de vista metafórico, como lenguaje ensamblador: hay algunas similitudes. ¿Se podría diseñar un compilador que pudiera convertir un lenguaje más natural, un lenguaje superior, en expresiones regulares? Luego, en mi código, podría definir mis expresiones regulares usando el lenguaje de nivel superior en un archivo de encabezado y hacer referencia a ellos cuando sea necesario utilizando una referencia simbólica. Yo y otros podríamos referirnos desde mi código al archivo de encabezado y apreciar más fácilmente lo que estoy tratando de lograr con mis expresiones regulares.
Sé que se puede hacer desde un punto de vista lógico; de lo contrario, las computadoras no serían posibles, pero si ha leído hasta aquí, ¿consideraría invertir el tiempo en darse cuenta?
¿Ha considerado usar un generador de analizadores (también conocido como compilador de compiladores) como ANTLR ?
ANTLR también tiene algún tipo de IDE ( ANTLR Works ) donde puede visualizar / depurar analizadores.
Por otro lado, un generador de analizador no es algo que arrojar en tu aplicación en unos pocos segundos, como una expresión regular, y también sería una exageración total para algo como verificar el formato de la dirección de correo electrónico.
También para situaciones simples esto sería una exageración total y tal vez una mejor manera sea simplemente escribir comentarios para su expresión regular explicando lo que hace.
¿Qué hay de escribirlos con Regex Buddy y pegar la descripción que genera como comentario en tu código?
El "modelo de contenido" de XML Schema es un ejemplo de lo que desea.
c(a|d)+r
se puede expresar como un modelo de contenido en XML Schema como:
<sequence>
<element name="c" type="xs:string"/>
<choice minOccurs="1" maxOccurs="unbounded">
<element name="a" type="xs:string"/>
<element name="d" type="xs:string"/>
</choice>
<element name="r" type="xs:string"/>
<sequence>
Relax NG tiene otra forma de expresar la misma idea. No tiene que ser un formato XML en sí mismo (Relax NG también tiene una sintaxis equivalente no XML).
La legibilidad de la expresión regular se reduce con todo el escape necesario, y un formato como el anterior reduce la necesidad de eso. La legibilidad de expresiones regulares también se reduce cuando la expresión regular se vuelve compleja, porque no hay una forma sistemática de componer expresiones regulares más grandes de las más pequeñas (aunque puede concatenar cadenas). La modularidad generalmente ayuda. Pero para mí, la sintaxis más corta es tremendamente más fácil de leer (a menudo convierto modelos de contenido XML Schema en expresiones regulares para ayudarme a trabajar con ellos).
Las expresiones regulares (bueno, las expresiones regulares "reales", ninguna de esas cosas modernas;) son máquinas de estados finitos. Por lo tanto, crea una sintaxis que describe expresiones regulares en términos de estados, bordes, entrada y posiblemente etiquetas de salida. Las fsmtools de AT & T son compatibles con algo así, pero están lejos de ser una herramienta lista para el uso diario.
El lenguaje en XFST , el kit de herramientas de estado finito de Xerox, también es más detallado.
Aparte de eso, diría que si su expresión regular se vuelve demasiado compleja, debería pasar a algo con más poder expresivo.
Nunca me encontré con algo así. Y no creo que algo así sea útil.
Ese lenguaje de alto nivel sería muy prolijo y creo que necesitarías declaraciones bastante largas para llegar a una expresión regular de complejidad promedio.
Tal vez simplemente no has estado usando expresiones regulares con la suficiente frecuencia. Créame, mi memoria está lejos de ser eidética (o incluso buena), pero rara vez tengo problemas para crear expresiones regulares o entender las de mis compañeros de trabajo.
Una forma de evitar este problema es mediante el uso de programas como QuickREx, que muestra cómo funciona la expresión regular en múltiples datos de prueba (con iluminaciones). Podrías guardar datos de texto en un archivo cerca de tu expresión regular y luego cuando quieras cambiarlo, entenderlo o arreglarlo, lo que sería mucho más fácil.
Estoy de acuerdo en que la sintaxis del ruido de línea de las expresiones regulares es un gran problema, y ​​francamente no entiendo por qué tanta gente lo acepta o defiende, no es legible para los humanos.
Algo que no menciona en su publicación, pero que es casi tan malo, es que casi cada idioma, editor o herramienta tiene su propia variación en la sintaxis de la expresión regular. Algunos de ellos soportan la sintaxis POSIX como se definió hace muchos años, algunos soportan la sintaxis de Perl como lo es hoy. Pero muchos tienen sus propias formas independientes de expresar cosas, o qué caracteres son "especiales" (los caracteres especiales son otro tema) y cuáles no. Lo que se escapó y lo que no. Etc. No solo es difícil leer una expresión regular escrita para un idioma o herramienta, sino que incluso si memorizas totalmente las reglas de sintaxis de tu variación favorita, pueden hacerte tropezar en un idioma diferente, donde ya no {2,3} significa lo que esperas Es realmente un desastre.
Además, creo que hay muchos no programadores que (si supieran que existía) apreciarían tener un lenguaje de coincidencia de patrones que pudieran usar en herramientas cotidianas como Google o Microsoft Word. Pero debería haber una sintaxis más fácil para eso.
Entonces, para responder a su pregunta, a menudo he pensado en crear algún tipo de biblioteca multiplataforma, cross-language, cross-everything que le permita "traducir" desde cualquier sintaxis de expresiones regulares (ya sea Perl, POSIX o Emacs , etc.) en cualquier otra sintaxis de expresiones regulares. Para que no tenga que preocuparse si las expresiones regulares de Python pueden hacer un look-back negativo, o si se deben escapar los corchetes de la clase de caracteres en una expresión regular de Emacs. Podrías simplemente memorizar una sintaxis, luego hacer una llamada a función para obtener la sintaxis equivalente para lo que sea que estuvieras usando.
A partir de ahí, podría ampliarse con un nuevo lenguaje de coincidencia de patrones, que sería un poco más detallado o al menos más nemotécnico. Algo para las personas que no quieren pasar media hora estudiando una expresión regular para descubrir qué es lo que hace. (Y las personas que piensan que las expresiones regulares están bien tal como son, obviamente nunca tuvieron que mantener algo que ellos mismos no escribieron, o comprenderían la necesidad de que otras personas puedan analizar lo que escribieron).
¿Alguna vez intentaré semejante bestia? No sé, ha estado en mi lista de cosas por hacer durante mucho tiempo, y también hay muchos proyectos más fáciles y entretenidos allí. Pero si estás contemplando algo similar, házmelo saber.
compilador de expresiones regulares:
ftp://reports.stanford.edu/pub/cstr/reports/cs/tr/83/972/CS-TR-83-972.pdf
1) Perl permite que /x
cambie las expresiones regulares para permitir que los comentarios y los espacios en blanco se incluyan dentro de la expresión regular. Esto hace posible extender una expresión regular compleja en varias líneas, usando sangrías para indicar la estructura del bloque.
2) Si no le gustan los símbolos que se asemejan al ruido de línea, no es demasiado difícil escribir sus propias funciones que crean expresiones regulares. Por ejemplo, en Perl:
sub at_start { ''^''; }
sub at_end { ''$''; }
sub any { "."; }
sub zero_or_more { "(?:$_[0])*"; }
sub one_or_more { "(?:$_[0])+"; }
sub optional { "(?:$_[0])?"; }
sub remember { "($_[0])"; }
sub one_of { "(?:" . join("|", @_) . ")"; }
sub in_charset { "[$_[0]]"; } # I know it''s broken for '']''...
sub not_in_charset { "[^$_[0]]"; } # I know it''s broken for '']''...
Entonces, por ejemplo, una expresión regular para hacer coincidir una cadena entre comillas ( /^"(?:[^//"]|//.)*"/
) se convierte en:
at_start .
''"'' .
zero_or_more(
one_of(
not_in_charset(''////"''), # Yuck, 2 levels of escaping required
''////' . any
)
) .
''"''
El uso de esta estrategia de "funciones de creación de cadenas" se presta a expresar bloques de construcción útiles como funciones (por ejemplo, la expresión regular anterior podría almacenarse en una función llamada quoted_string()
, podría tener otras funciones para hacer coincidir cualquier valor numérico, una dirección de correo electrónico, etc.).
Veo un montón de respuestas tratando de resolver el problema, pero creo que tengo una respuesta para ti.
Creo que toda la sintaxis de expresiones regulares vino de finales de los 70. (Desearía poder encontrar algún tipo de historia sobre el tema) Recogí un libro de 1979 sobre autómatas de letras y todo el libro está lleno de pruebas matemáticas sobre cómo encontrar patrones en el texto. Conseguiré el título cuando llegue a casa y lo actualizaré aquí.
El caso es que este libro tenía algunos símbolos muy complicados en relación con el cálculo que, de no haber estudiado tal clase, no podría entenderlo. Apuesto, sin embargo, un matemático que regularmente usa esta sintaxis podría leerlo como una novela.
Me llevó un buen mes entender cómo leer expresiones regulares hasta el punto que solo necesito echarle un vistazo. Para la persona laica parece un asm complicado con todos estos símbolos extraños. No considero expresiones regulares como ensamblaje, es una fórmula matemática para encontrar patrones en el texto. Considerando la sintaxis y que viene originalmente del matemático, no creo que esté lejos.
En cuanto a un compilador, dudo que pueda haberlo. Como dmckee mencionó "Noté, sin embargo, que a muchas manos viejas no parece gustarles". Tienes dibujos animados y comedias de situación que representan complicadas ecuaciones matemáticas en pizarras. Es una broma mostrar cuán difícil es un tema en particular, pero en realidad cualquier persona con experiencia podría entenderlo si se les da el subtexto y un poco de entrenamiento. Regex no es difícil. Una vez que obtienes lo básico, todo se reduce al analizador en particular que usas. Es como si algunos niños me dijeran que no quieren aprender C / C ++ porque es más difícil que Javascript incluso si tiene la misma sintaxis. Su percepción más que dificultad.
Una vez que haya aprendido Regex, son los motores que le dan problemas. Visual Studio usa corchetes en lugar de paréntesis para agrupar. La biblioteca de expresiones regulares simple SLRE que uso tiene un subconjunto simple frente a la sintaxis más completa de PCRE . En este punto, comenzamos a hablar de un lenguaje más nuevo en lugar de una herramienta para el ajuste de texto.
Además, la mayoría de los programadores usan una sola línea corta para sus coincidencias de expresiones regulares en lugar de crear una coincidencia completa de expresiones regulares porque solo desean analizar algunos datos aleatorios. La coincidencia de Regex es una herramienta como Bison, yacc o ANTLR. Un analizador construido a mano siempre será mejor así que, en esencia, puede compilar su propia expresión regular, entonces, ¿por qué pasar el tiempo con 2 páginas de código para una coincidencia de expresiones regulares cuando un ciclo simple de ansi c while es más rápido?
Si quieres que Regex sea más dinámico y legible, es mejor construir tu analizador en el idioma nativo que usas para tu programa. Regex está destinado a ser una herramienta y no un lenguaje completo.
Como nota al margen, observe algunos de los códigos fuente de Lua entre Lua 3.0 y 3.2.2. Cambian de un analizador de Bison a uno creado a mano. Se da cuenta de cuánto más libertad tienen con eso que utilizando una herramienta para hacer su análisis de texto, especialmente con las últimas versiones de características. Por supuesto, también hace que sea más complicado un código para mantenerse actualizado. Era una elección entre la claridad de los archivos * .y la solidez de ser construido a mano.
Tal vez algunas herramientas de JavaScript pueden ayudar:
- Visualice RegEx que es bastante sorprendente, también está en GitHub
- Evaluar RegEx de varias maneras
- Regex Evaluator con algunos sintaxis hilighting
- Quick RegEx evaluator con algunas expresiones regulares útiles
Tristemente, no encontré ninguna herramienta JS lista para usar, apuntar y hacer clic, para construir y manipular fácilmente RegEx. El poder de RegEx (PCRE, Posix, Python) es que ellos
- son extremadamente compactos (uno puede argumentar bastante compacto)
- se puede usar en casi todos lados
- siempre se ven iguales (un tamaño incómodo se ajusta a todos) y por lo tanto son fáciles de detectar en el código
Así que reinventar la rueda quizás no sea la mejor opción, y las expresiones regulares ya están compiladas internamente para acelerar mucho las cosas. Si busca algo más elaborado, hay LEX y YACC (y sus sucesores), pero la mayoría de las veces exageran las cosas en comparación con la forma sencilla en que se puede aplicar RegEx.
Lo siguiente podría ser útil para otros, pero no es Linux, así que no pude probarlo:
Si encuentra otros enlaces buenos, quizás los agregue como comentario. Sé que esto es un poco de abuso para solicitar esto, pero es increíblemente útil. Gracias.
Hay formas de hacer que las RE en su forma habitual sean más legibles (como la sintaxis perl /x
) y varios lenguajes mucho más prolijos para expresarlas. Ver:
- https://.com/questions/263072/why-are-regular-expressions-such-a-complicated-cryptic-mess
- ¿Por qué la gente defiende la sintaxis de expresiones regulares?
Observo, sin embargo, que a muchos viejos no parece gustarles.
No existe una razón fundamental por la que no se pueda escribir un compilador para un lenguaje de RE con gran cantidad de palabras que se dirija a uno compacto, pero no veo ninguna gran ventaja en él. Si te gusta la forma prolija, solo úsala.
Si lees el Dragon Book para compiladores, te dice que uses regex para analizar y analizar tu lenguaje de nivel superior. Entonces, las expresiones regulares parecen ser algo más bajo. Los uso muy a menudo en mis tareas de trabajo diarias para el desarrollo de frontend / backend y sí, encontré que algunos de ellos son algo crípticos. Sin embargo, eso no hace mal la expresión regular, siempre puedes escribir un nuevo idioma si no te gustan, dado que 1) tienes el tiempo 2) estás dispuesto a poner el esfuerzo adecuado 3) la fuerza es fuerte dentro de ti tú :)