No estoy preguntando dónde aprender. He encontrado muchos buenos recursos en línea, libros, etc.
Pero cómo diablos los abordo. ¿Dónde está el comienzo, el final? ¿Cuándo avanza el procesador regexp sobre el texto, cuándo mantiene su posición e intenta otra coincidencia? etc.
Tengo ganas de tratar de descubrir jeroglíficos en las pirámides egipcias.
learning
regular-expressions
dumbBoy
fuente
fuente
Respuestas:
Creo que el conocimiento de la teoría de Automata es crítico para la comprensión.
Una vez que comprenda qué es un autómata y cómo se definen los lenguajes regulares , será mucho más fácil comprender las expresiones regulares .
En cuanto a la sintaxis específica y las diferencias entre las diversas implementaciones ... Bueno, algunas cosas solo tienes que recordar. También hay ayudas para eso.
Editar
Algunos de los comentarios a continuación plantearon puntos importantes:
No olvide que las expresiones regulares (como se implementan en la mayoría de los lenguajes de programación) son un superconjunto de expresiones regulares en la teoría de autómatas. Si bien una buena base teórica es un lugar útil para comenzar, no le dirá todo. (Gracias, David Thornley)
Varios comentaristas dicen que es posible aprender las diversas sintaxis de expresiones regulares sin conocer las bases teóricas. Si bien es cierto que puede aprender la sintaxis sin comprender completamente cómo funciona, tuve la impresión de que la comprensión total es lo que buscaba el OP. La pregunta era sobre la base real: ¿cuándo avanza el procesador? ¿Cuándo se detiene? ¿Cómo decide que es un partido? Esa es la base, esa es la teoría, y se basa en la Teoría de Autómatas. Claro, puedes conducir un automóvil sin saber cómo funciona el motor. Pero si le preguntan "cómo funciona realmente el gas", debe hablar sobre cómo está construido el motor, ¿no?
fuente
Practicando
Aprendí divirtiéndome con el raspado web. Estoy seguro de que no estaba solo haciendo eso solo por diversión.
Un ejemplo: escriba un código que recupere los últimos puntajes de fútbol, tenis (el deporte que le gusta de hecho) de su sitio web de deportes favorito. Hágalo escribiendo algún código para cargar la página, extraer las puntuaciones con expresiones regulares y enviarlas a la consola o a algún archivo de texto. Asegúrese de que con la expresión regular que elija solo recupere los puntajes, y nada más. A veces esto puede ser bastante desafiante :-)
Segundo ejemplo: escriba un código que recupere la imagen de su webcomic favorito ( por ejemplo , me gusta mucho Sinfest ) y que lo almacene en algún lugar de su disco duro. Use solo expresiones regulares para recuperar la etiqueta "img" y su contenido. Opcionalmente, también recupere su título si está almacenado en algún lugar.
fuente
Sé que no estás pidiendo recursos, pero Dominar expresiones regulares por Jeffrey EF Friedl fue cómo aprendí cómo funcionan y cómo usarlos. Incluso después de llegar al punto de usar muchos de ellos para analizar diferentes cosas, el primer capítulo tenía cosas nuevas para mí.
¿Quieres entender esas malditas expresiones regulares? Lee este libro.
fuente
Comenzaría por aclarar sus objetivos y luego descubrir su estilo de aprendizaje .
Lo que me llamó la atención de tu pregunta es que preguntas "¿cómo aprendo expresiones regulares?" e inmediatamente siga eso con la pregunta "¿cómo funciona internamente el motor de expresión regular?" Parece estar insinuando que esas dos cosas tienen algo que ver entre sí, lo cual es un punto revelador. Quizás eres una persona que aprende cómo funciona algo al desarmarlo o al construirlo tú mismo.
Para las aplicaciones para principiantes, generalmente no es necesario comprender cómo funciona una herramienta para usarla de manera efectiva. No necesita saber cómo funciona un motor de perforación para hacer agujeros en la madera; debe comprender cómo usar el ejercicio, no cómo construir un ejercicio.
Entonces, ¿cuál es tu objetivo? ¿Tiene la intención de aprender a construir un motor de expresión regular? ¿O tiene la intención de aprender cómo utilizar efectivamente las expresiones regulares para resolver problemas comerciales? Lograr esos objetivos diferentes probablemente requiere diferentes técnicas de aprendizaje.
Para abordar su pregunta específica sobre cómo funciona el motor de expresión regular: depende. El enfoque teórico "clásico" de las expresiones regulares es utilizar la expresión regular como modelo para un autómata finito no determinista, luego construir el autómata finito determinista equivalente y luego ejecutar ese autómata contra la entrada.
Casi nadie realmente hace esto por varias razones. Primero, el número de estados multiplicado por el número de caracteres de entrada posibles produce una tabla de transición de estado que es enorme incluso para expresiones regulares pequeñas. Claro, la mayor parte de eso se puede comprimir, pero aún así, son muchas reglas de transición. En segundo lugar, otros enfoques suelen ser más rápidos. Tercero, las denominadas expresiones "regulares" se encuentran en las bibliotecas regexp modernas, nada de eso. No son idiomas regulares en absoluto; a menudo son reconocidos por autómatas pushdown, no por lenguajes de autómatas finitos.
(Comencé a escribir una larga serie sobre cómo funciona todo esto, pero me quedé sin fuerzas después de solo los primeros doce artículos . Puede encontrarlos interesantes si desea una breve introducción sobre el trasfondo teórico de las expresiones regulares básicas).
Los motores de expresión regular reales en su lugar suelen utilizar una estrategia de retroceso. El motor de expresión regular que creamos para el motor JScript hace más de una década ahora compila la expresión regular en un lenguaje de código de bytes que incluye primitivas para reconocer secuencias y retroceder a estados anteriores. Luego construimos un intérprete para ese lenguaje de código de bytes.
No trataría de entender cómo funciona un motor regexp antes de tener una comprensión bastante sólida de cómo usar expresiones regulares. Concéntrese en eso antes de comenzar a profundizar en las estrategias de optimización de varios motores diferentes.
fuente
"[0-9]{3}"
que puede coincidir con cualquier número de tres dígitos, y el número 480 de tres dígitos es un ejemplo para un regular expresiones con las que coincide.Como cualquier cosa nueva:
Estudiar
Encuentro que la mayoría de los maestros exitosos comienzan a enseñar cualquier materia proporcionando primero un poco de antecedentes sobre la materia. Es importante tener un contexto de lo que está aprendiendo y, lo más importante, por qué lo está aprendiendo.
Todo coincide con la cadena
Las expresiones regulares son un medio de hacer coincidir patrones en el texto. Es un lenguaje declarativo incorporado en muchos otros lenguajes de programación.
Me gustaría enfatizar que es un lenguaje declarativo, las expresiones regulares son útiles para expresar qué cadena debe coincidir, pero de ninguna manera expresan cómo el programa debe hacer la coincidencia. Por esta razón, es posible usar expresiones regulares muy rápida y muy lentamente en el mismo lenguaje de programación simplemente usando un analizador RegEx diferente.
La razón para crear expresiones regulares es la misma para la creación de la mayoría de los lenguajes de programación: los programadores se encontraron realizando la misma tarea complicada una y otra vez y decidieron que querían una forma más simple de escribir el código.
Algunos se quejarán (y deberían) sobre mi oración anterior diciendo algo como:
RegEx no simplifica un programa.
es verdad
RegEx no simplifica un programa, RegEx simplifica la escritura del programa. Aún debe ser exhaustivo en sus pruebas para asegurarse de que todos los casos correctos coincidan correctamente y que todos los casos incorrectos no. Es realmente difícil probar "todos", y con patrones complicados, es realmente difícil probar "la mayoría". En el peor de los casos, aún debería estar probando "algunos" casos.
incorporemos algunos ejemplos que he elegido obligatoriamente el motor RegEx de JavaScript porque puedo probarlo en vivo en el navegador fácilmente y porque no tendré que hacer ningún escape de cadena mientras uso literales RegEx.
Cuando hace una coincidencia de cadena normal, prueba un valor de cadena contra otro. Pueden venir de cualquier parte, pero al final se necesitan dos cadenas que se comparan entre sí:
Ese ejemplo apesta porque nunca hará nada
Mucho mejor; ahora, en realidad no sabemos de antemano si se hará algo o no. Ahora podemos comenzar a aceptar la entrada del usuario:
Maravilloso, ahora los usuarios pueden ingresar
bar
y sucederá algo, hasta que reciban informes de errores de los usuarios que dicen que"bar"
no está funcionando, o que "BAR" no está funcionando, o que han escritoBRA
100 veces y nunca pasa nada.Ignorando los errores ortográficos y los caracteres adicionales, los
'bar' != 'BAR'
programadores deben pensar en una forma de probar dónde están los caracteres en el caso equivocado.Solución simple, uso
toLowerCase
. Eso funciona de maravilla, pero ¿qué pasa con nuestros usuarios que utilizan el inglés británico sobre el inglés americano cuando estás haciendo coincidirsomething == 'color'
? Ahora tendrás que coincidirsomething == 'color' || somthing == 'colour'
.En pocas palabras, los patrones simples se convierten en muchos códigos repetitivos muy rápidamente.
El ejemplo de color simplemente se puede combinar con:
Una comprensión sólida de los conceptos básicos de las expresiones regulares puede reducir significativamente la cantidad de tiempo que desperdicia reinventando la rueda.
Donde estudiar
La mayoría de los idiomas que implementan expresiones regulares tienen al menos un recurso disponible para la sintaxis específica del uso de expresiones regulares dentro de ese idioma. Uno para JavaScript se puede encontrar en MDN
Léelo.
todo ello.
luego léelo de nuevo.
Toma tiempo aprender, piense en ello como una inversión: una hora para aprender RegEx ahora ahorra una hora la próxima vez que necesite hacer alguna coincidencia de patrones de cadena, y luego otra hora la próxima vez.
Práctica
Después de leer todo sobre RegEx, probablemente no entenderás la mayor parte. Eso es porque en realidad no estás haciendo nada con eso.
Mencioné por qué elegí JS para este ejemplo, le insto a que lo juegue en su navegador. Es rápido y puede hacerlo directamente en su barra de URL.
JS tiene algunas formas diferentes y simples de usar RegEx:
Comenzando con algo simple como:
Es una manera fácil de poner el pie en la puerta. Juega con él, rómpelo para ver qué coincide y qué no.
Cuando te quedes atascado en la práctica, continúa
30
. Necesita leer para aprender más, pero necesita practicar para comprender realmente lo que ha aprendido.fuente
Brian Kernighan escribe un sencillo procesador reg-ex en el libro Beautiful Code . Me doy cuenta de que no está buscando recursos, pero podría ser útil ver una implementación básica en el interior.
fuente
En el desarrollo normal, el código de depuración puede proporcionar información muy útil. Las expresiones regulares no son diferentes. Entonces, a riesgo de sonar como un anuncio, obtén RegexBuddy . Tiene una gran herramienta para mostrar visualmente lo que está haciendo el motor, ya que maneja su expresión y la cadena de entrada.
fuente
Las expresiones regulares pueden volverse muy complicadas muy rápidamente, por lo que le recomendaría que comience a aprenderlas utilizando tutoriales. Sepa que la forma más simple de expresión regular es una cadena que representa lo que está buscando. Desafortunadamente, para poder definir reglas de búsqueda especiales, se requieren ciertos caracteres, y estos caracteres deben escaparse o se creará una expresión regular no válida o incorrecta.
Mi consejo es comenzar con un ejemplo de algo que estás buscando y escapar de él. En otras palabras, si estaba buscando algo entre paréntesis, tome un ejemplo de una de esas cadenas en el texto que está buscando:
(this is an example of something you'd want to find)
Comience por escapar de los caracteres para buscar el carácter literal:
\(this is an example of something you'd want to find\)
Pruébelo, verifique que encuentre su ejemplo correctamente. Luego generalice la expresión para encontrar cualquier texto, no solo el ejemplo que encontró. Entonces se convertiría en:
\([^)]*\)
(significa cualquier carácter que no sea ")" para cualquier número de ocurrencias, incluido 0).Pruébelo nuevamente y verifique que no solo encuentre su ejemplo, sino que a otros les guste. Busque expresiones regulares más complicadas pero más frecuentes en Internet y parchelas con sus expresiones regulares existentes para evitar tener que preocuparse por cada posibilidad.
Eso es todo. Y oh, aprende y ama \ Q ... \ E. En la mayoría de los lenguajes de expresión regular, \ Q indica el comienzo de un patrón literal y \ E marca el final, en caso de que tenga que lidiar con la búsqueda de patrones particularmente sofisticados y no sepa cómo escapar de ellos. Eso me salvó la vida más de un par de ocasiones.
fuente
Te daré una respuesta simple para una pregunta simple. Primero, debe comprender qué son las expresiones regulares (RegEx): qué hacen, para qué se utilizan. Entonces, una gran herramienta para comenzar.
¿Qué es? RegEx es un lenguaje para expresar coincidencia de patrones. Es decir, usándolo, puede crear una combinación de caracteres que reconozca o encuentre patrones en el texto. ¿Cómo es esto útil? En la programación, puede decirle a las computadoras que coincidan con el texto de alguna fuente (una entrada del usuario, una página web, etc.) y detectar si hay patrones específicos de texto contenidos o no en él. Por ejemplo, un punto (.) Representa cualquier carácter: letra o número. Los números entre llaves representan números de iteraciones, por lo que ". {1,30}" indica cualquier carácter, repetido entre 1 y 30 veces; en otras palabras, no puede tener una cadena vacía y no puede tener más de 30 caracteres. Y continúa desde allí.
¿Cómo empezar a aprender? La mejor herramienta absoluta que he visto es Expresso , pero es solo para Windows. Tiene una interfaz gráfica de usuario muy extensa donde hace clic en los elementos que desea agregar a su expresión, luego un probador para compararlo con varias entradas para ver los resultados. No he visto nada bueno en Mac (pero estoy ejecutando Windows en VMWare, así que realmente no necesito una versión para Mac), no he pasado mucho tiempo buscando en Linux.
fuente
Además de una buena referencia, la forma en que realmente aprende es usar buenas herramientas de aprendizaje. Uno está utilizando el editor de código abierto Vim , con dos opciones establecidas:
El otro es usar una herramienta gratuita llamada RegExCoach . Pega el texto que desea buscar, luego en otra ventana desarrolla su expresión regular. Al igual que Vim, destaca partidos exitosos sobre la marcha.
fuente
Empiezas con una comparación básica de cadenas. Muy fácil, pero tampoco tan poderoso.
A continuación, puede que te haya ocurrido que necesitas comparaciones entre mayúsculas y minúsculas, de modo que "griego" y "griego" se comparen de la misma manera. Esto es un poco más poderoso.
Un día observa que pequeñas diferencias en la ortografía no deberían evitar que 2 palabras se comparen igual: es decir, "organizar" y "organizar" deben comparar igual. Te sientas y escribes un código que hace esto y eres feliz.
Hasta que resumas un poco más y te des cuenta de que a veces quieres que todas las palabras que terminan en "ize" se comparen con sus hermanos en la ortografía británica. O, las repeticiones de algunas cadenas una cierta cantidad de veces. Y, por supuesto, necesitas combinar todo eso.
Y así. Finalmente, lo más probable es que termines con alguna notación donde no todos los personajes se destacan por sí mismos. Nada más es una expresión regular. Uno puede verlo como una descripción de un conjunto de cadenas.
Y luego, es bastante fácil y se reduce a los siguientes 3 principios básicos:
Tiene expresiones regulares básicas: caracteres que representan a sí mismos, clases de caracteres, abreviaturas prácticas y no tan prácticas para clases de caracteres como \ d o \ p {Lu} para letras mayúsculas.
Y luego, tiene algunas posibilidades de combinarlos: si r1 y r2 son expresiones regulares, entonces también lo son r1r2 r1 | r2 (r1).
Por último, pero no menos importante, los modificadores de repetición: r? r * r + r {n, m}
Esto es lo que más necesitas saber. Cualquier otra cosa que pueda buscar cuando lo necesite.
fuente
Otras dos buenas respuestas te dicen que aprendas la teoría detrás de las expresiones regulares y que practiques, que son excelentes consejos. También recomiendo obtener una buena herramienta visual de expresiones regulares para ayudarlo si habla en serio.
RegexBuddy , por ejemplo, tiene un modo de depuración visual que le permite pasar por la ejecución de una expresión regular, y le muestra a través de resaltados y texto explicativo qué está haciendo el motor de expresiones regulares en cada paso. Hay un video que demuestra esta depuración en su sitio.
fuente
Todo lo que podemos darle es más recursos para aprender. Esta pregunta es en sí misma un recurso.
Por cierto, he aprendido expresiones regulares con bastante facilidad de este sitio: http://www.regular-expressions.info/
fuente
Para mí, ver qué coincide con la expresión regular mientras la estoy construyendo realmente ayuda a hacerme la vida más fácil y me ha ayudado a comprenderlos mejor.
Para hacer esto, abriré un archivo con el texto de destino en Emacs y luego usaré el
isearch-forward-regexp
comando. A medida que ingresa la expresión regular, Emacs le muestra con qué coincide (esa es la parte "isearch").Para ejecutar el comando, en Emacs, puede usar
<ESC>xisearch-forward-regexp
.fuente
Aprendí expresiones regulares aprendiendo flex y bison, que se utilizan para construir analizadores y analizadores léxicos. No podrías tener un analizador sin expresiones regulares, y el libro lexx y yacc es increíblemente bueno para seguir la teoría sin moverte demasiado rápido.
Fundamentalmente, prácticamente todos los motores regex en estos días siguen los mismos principios. Son todas máquinas de estados finitos y si realmente lo asimilas, entonces tienes ventaja sobre casi cualquier código que escribas. Es similar al aprendizaje de la recursividad en que, una vez que lo obtienes, lo aplicas a los problemas instintivamente. Son fáciles de resolver con la herramienta adecuada, pero muy difíciles sin ella.
Otra cosa acerca de aprender lexx y yacc, en comparación con las expresiones regulares, es aprender cómo funcionan internamente. La forma en que el programa mira hacia adelante, por qué finaliza una coincidencia, cómo almacena los datos y mucho más. Comprender los punteros es una necesidad absoluta, pero si obtienes lexx y yacc, y lo revisas desde el principio, aprenderás todo lo que pediste y tendrás una herramienta enormemente poderosa para el resto de tu carrera.
Esta pregunta incluye un montón de recursos para el aprendizaje y un esqueleto flexible que reuní.
fuente
Además, primero trato de asegurarme de que no haya una manera más fácil de resolver el problema / "tokenizar" la cadena.
Cuando no puede encontrar uno, lo veo como un problema, no de tratar de hacer coincidir lo que quiere de la cadena, sino que es una cuestión de NO hacer coincidir lo que no quiere. Esto se debe principalmente a que las expresiones regulares son codiciosas. Pero me ha servido como un enfoque para obtener lo que quiero.
Aquí hay un ejemplo:
para que coincida con el minuto:
En lugar de tratar de encontrar el tiempo junto con todo lo demás, trate de encontrar los límites distintos.
El ejemplo es un poco artificial, pero todo lo que se me ocurrió.
fuente
Un enfoque que utilicé fue encontrar un montón de proyectos de código abierto que necesitaban actualizaciones de sintaxis y luego escribir un script sed cada vez más complejo, que constaba de muchas expresiones regulares.
El script necesitaba ejecutarse contra muchos archivos diferentes en cada proyecto de código abierto. Luego se ejecutará contra muchos proyectos diferentes con diferentes estilos. Comencé con algo muy simple como
%s/before/after
entonces encontré que coincidía con muchos casos. así que agregué más cosas para evitar eso. Luego encontré diferentes proyectos usando diferentes estilos de sintaxis que necesitaban diferentes cambios.Al final terminé con
y fue ayudado en este enfoque por la necesidad de
También le diré que hay un montón de sitios para los distintos idiomas: ruby, javascript, etc. que le permitirán jugar con expresiones y textos de muestra para una satisfacción inmediata. Estos son:
expresiones regulares en varios idiomas en un sitio
centrarse en los grupos de partidos:
fuente
He descubierto que aprender expresiones regulares es similar al aprendizaje de las tablas de multiplicar: sí, debe comprender las ideas detrás de esto, pero en última instancia, solo tiene que hacerlo con frecuencia y repetidamente.
Cuando estaba aprendiendo, me propuse hacer algunos ejercicios de expresiones regulares por día. En la práctica, esto significaba que al menos una vez al día, trataría de ver una cadena o texto en mi pantalla, y presentar un desafío: "¿puedo obtener todas las direcciones de correo electrónico de aquí" o "encontrar todos los ocurrencias de la palabra 'código' usado como un verbo en lugar de un sustantivo, "cosas así.
Hacerlo durante unas semanas realmente valió la pena, y por supuesto, se necesitan revisiones periódicas y actualizaciones. Estoy a punto para uno.
También encontré útil esta herramienta en línea, ya que me permite probar regex en tiempo real: http://www.gethifi.com/tools/regex
fuente