¿Cómo aprendes las expresiones regulares? [cerrado]

80

No estoy preguntando dónde para aprender. He encontrado muchos buenos recursos en línea, y libros, etc.

Pero, ¿cómo diablos los abordo? ¿Dónde está el comienzo, el final? ¿Cuándo avanza el procesador de expresiones regulares 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.

    
pregunta dumbBoy 17.04.2014 - 22:33

18 respuestas

67

Creo que el conocimiento de la Teoría de autómatas es fundamental para la comprensión.

Una vez que entienda qué es un autómata y cómo se definen los lenguajes regulares , entienda el expresiones regulares será mucho más fácil.

En cuanto a la sintaxis específica y las diferencias entre las distintas implementaciones ... Bueno, hay algunas cosas que debes recordar. También hay ayudas para eso.

Editar

Algunos de los comentarios a continuación plantearon puntos importantes:

  1. 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 un buen fondo teórico es un lugar útil para comenzar, no te lo dirá todo. (Gracias, David Thornley)

  2. 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 completa es lo que buscaba el OP. La pregunta era sobre la base real: ¿cuándo avanza el procesador? Cuando 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 los autómatas. Claro, puedes conducir un auto sin saber cómo funciona el motor. Pero si le preguntan "cómo hace que el gas realmente lo haga funcionar", usted tiene que hablar sobre cómo se construye el motor, ¿no?

respondido por el littleadv 18.04.2014 - 01:26
36

Al practicar.

Aprendí divirtiéndome con raspado web. Estoy seguro de que no estaba solo haciendo eso solo por diversión.

Un ejemplo: escriba un código que recupere las últimas puntuaciones de fútbol, tenis (el deporte que le gusta) en su sitio web de deportes favorito. Hágalo escribiendo algún código para cargar la página, extraiga las puntuaciones con expresiones regulares y envíelas a la consola oa 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 eso almacena en algún lugar de tu disco duro. Use solo expresiones regulares para recuperar la etiqueta "img" y su contenido. Opcionalmente, también recupera su título si está almacenado en algún lugar.

    
respondido por el Jalayn 25.09.2011 - 12:18
23

Sé que no estás pidiendo recursos, pero Dominar expresiones regulares por Jeffrey EF Friedl fue lo que 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 esos malditos regexp? Lee este libro.

    
respondido por el Arkh 23.09.2011 - 09:41
19
  

¿Dónde está el comienzo, el final? ¿Cuándo avanza el procesador de expresiones regulares sobre el texto, cuándo mantiene su posición e intenta otra coincidencia? etc.

Comenzaría por aclarar tus objetivos y luego descubrir tu estilo de aprendizaje .

Lo que me llamó la atención de tu pregunta es que preguntas "¿cómo puedo aprender expresiones regulares?" y luego continúe con la pregunta "¿cómo funciona internamente el motor de expresiones regulares?" Parece que estás insinuando que esas dos cosas tienen algo que ver entre sí, lo cual es un punto revelador. Tal vez eres una persona que aprende cómo funciona algo desarmándolo o construyéndolo tú mismo.

Para las aplicaciones para principiantes, generalmente no hay necesidad de entender cómo funciona una herramienta para utilizarla de manera efectiva. No es necesario saber cómo funciona un taladro para colocar 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 cómo construir un motor de expresiones regulares? o tiene la intención de aprender cómo usar expresiones regulares para resolver problemas de negocios? Para lograr esos objetivos diferentes probablemente sea necesario Diferentes técnicas de aprendizaje.

Para responder a su pregunta específica sobre cómo funciona el motor de expresiones regulares: depende. El enfoque teórico "clásico" de las expresiones regulares es utilizar la expresión regular como un plano para un autómata finito no determinístico, luego construir el autómata finito determinista equivalente y luego ejecutar ese autómata contra la entrada.

Casi nadie hace esto por varias razones. Primero, el número de estados multiplicado por el número de posibles caracteres de entrada produce una tabla de transición de estado que es increíblemente enorme incluso para pequeñas expresiones regulares. Claro, la mayoría 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. En tercer lugar, las denominadas expresiones "regulares" están en las bibliotecas regexp modernas, nada de eso. No son lenguajes regulares en absoluto; a menudo son reconocidos por autómatas pushdown, no por autómatas finitos.

(Comencé a escribir una larga serie sobre cómo funciona todo esto, pero me quedé sin vapor después de solo primeros doce artículos . Puede que te interesen si deseas una breve introducción sobre los antecedentes teóricos de las expresiones regulares básicas.)

Los motores de expresiones regulares reales, en cambio, suelen utilizar una estrategia de retroceso. El motor de expresiones regulares que creamos para el motor JScript hace más de una década ahora compila las expresiones regulares en un lenguaje de bytecode que incluye primitivas para el reconocimiento de secuencias y el retorno a los estados anteriores. Luego creamos un intérprete para ese idioma de código de bytes.

No intentaría entender cómo funciona un motor de expresión regular 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.

    
respondido por el Eric Lippert 22.09.2011 - 19:06
6
  

¿Cómo diablos los abordo?

Me gusta cualquier cosa nueva:

10 Study
20 Practice
30 goto 10

Estudio

Encuentro que los maestros más exitosos comienzan a enseñar cualquier materia al proporcionarles un poco de antecedentes. Es importante tener un contexto de lo que estás aprendiendo y, lo más importante, por qué lo estás aprendiendo.

Todo es coincidencia de cadenas

Las expresiones regulares son un medio para 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 la cadena con para que coincida, pero no expresan de ninguna manera cómo la Programa es ir haciendo el emparejamiento. Por esta razón, es posible usar expresiones regulares muy rápidamente 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 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 sencilla de escribir el código.

Algunos se quejarán (y deberían) quejarse de mi oración anterior diciendo algo como:

RegEx no hace que un programa sea más simple.

es cierto

RegEx no hace que un programa sea más simple, RegEx hace que escribir el programa sea más simple. Aún debe ser minucioso en sus pruebas para asegurarse de que todos los casos correctos coincidan correctamente y de que no todos los casos incorrectos. 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.

permite incorporar algunos ejemplos. He elegido obligatoriamente el motor RegEx de JavaScript porque puedo probarlo en vivo en el navegador fácilmente y porque no tendré que hacer ninguna cadena de escape mientras utilizo los literales RegEx.

Cuando haces una coincidencia normal de cadenas, pruebas un valor de cadena contra otro. Pueden venir de cualquier parte, pero al final se necesitan dos cadenas que se comparan entre sí:

if ( 'foo' == 'bar' ) doSomething();

Ese ejemplo apesta porque nunca hará nada

if ( foo == 'bar' ) doSomething();

Mucho mejor; ahora, no sabemos de antemano si algo se hará o no. Ahora podemos comenzar a aceptar comentarios del usuario:

if ( prompt( 'Say "bar" to do something.' ) == 'bar' ) doSomething();

Maravilloso, ahora los usuarios pueden ingresar bar y ocurrirá algo, hasta que reciba informes de errores de los usuarios que dicen que "bar" no funciona, o que "BAR" no funciona, o que han escrito BRA 100 veces y nunca pasa nada.

Ignorar las faltas de ortografía y los caracteres adicionales, 'bar' != 'BAR' , y los programadores deben encontrar una forma de probar dónde están los caracteres en el caso equivocado.

Solución simple, use toLowerCase . Eso funciona de maravilla, pero ¿qué pasa con nuestros usuarios que utilizan el inglés británico sobre el inglés estadounidense cuando coinciden con something == 'color' ? Ahora tendrás que hacer coincidir something == 'color' || somthing == 'colour' .

En pocas palabras, los patrones simples se convierten en muchos códigos repetitivos muy rápidamente.

El ejemplo de color puede combinarse simplemente con:

/colou?r/.test( something )

una comprensión sólida de los conceptos básicos de las expresiones regulares puede reducir significativamente la cantidad de tiempo que se pierde reinventando la rueda.

Dónde 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 eso.
luego léelo de nuevo.

Se necesita tiempo para aprender, considérelo como una inversión: una hora para aprender RegEx ahora ahorra una hora la próxima vez que necesite hacer una coincidencia de patrones de cadena, y luego otra hora la próxima vez después de eso.

Práctica

Después de leer todo sobre RegEx, es probable que no entiendas la mayoría. Eso es porque en realidad no estás haciendo nada con eso.

Mencioné por qué elegí JS para este ejemplo, le insto a que se meta con él en su navegador. Es rápido y puedes hacerlo directamente en la barra de URL.

JS tiene algunas formas diferentes y simples de usar RegEx:

string.match( regex )
regex.exec( string )
regex.test( string )

Comenzando con algo simple como:

javascript:'color'.match(/colou?r/);

es una manera fácil de poner tu pie en la puerta. Juega con él, divídelo, ve qué partidos y qué no.

Cuando te quedas atascado en la práctica, continúa con 30 . Necesitas leer para aprender más, pero necesitas practicar para entender realmente lo que has aprendido.

    
respondido por el zzzzBov 23.09.2011 - 03:36
5

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 ayudar a ver una implementación básica, en el interior.

    
respondido por el Michael Easter 22.09.2011 - 13:30
4

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 parecer un anuncio, obtenga RegexBuddy . Tiene una gran herramienta para mostrar visualmente lo que hace el motor mientras maneja tu expresión y la cadena de entrada.

    
respondido por el John Fisher 22.09.2011 - 19:23
3

Las expresiones regulares pueden llegar a ser muy complicadas muy rápidamente, por lo que te recomiendo que comiences 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 estarías creando una expresión regular inválida o incorrecta.

Mi consejo es comenzar con un ejemplo de algo que estés buscando y escapar. 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 escapando los caracteres para que busque 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 de nuevo 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 aplíqueles parches con las 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 en más de un par de ocasiones.

    
respondido por el Neil 22.09.2011 - 12:31
3

Le daré una respuesta simple para una pregunta simple. Primero, debe comprender qué son las expresiones regulares (RegEx): qué hacen, para qué se usan. Entonces, una gran herramienta para comenzar.

  1. ¿Qué es? RegEx es un lenguaje para expresar la coincidencia de patrones. Es decir, al usarlo, 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 indicar 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 dentro de la misma. 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 ser más larga que 30 caracteres. Y continúa desde allí.

  2. ¿Cómo empezar a aprender? La mejor herramienta que he visto es Expresso , pero solo para Windows. Tiene una GUI muy extensa en la que hace clic en los elementos que desea agregar a su expresión, luego un comprobador para verificar si hay varios datos para ver los resultados. No he visto nada bueno en la Mac (pero estoy ejecutando Windows en VMWare, así que realmente no necesito una versión para Mac), no he pasado mucho tiempo buscando Linux.

respondido por el Jay Imerman 22.09.2011 - 20:24
3

Además de una buena referencia, la forma en que realmente aprende es usar buenas herramientas de aprendizaje. Una es usar el editor de código abierto Vim , con dos opciones establecidas:

  1. : establezca incsearch ... a medida que escribe un patrón de búsqueda en la línea de comandos, el editor sobre la marcha salta a la primera parte del texto que coincide y resalta exactamente lo que coincide. Si escribes algo que hace que ya no coincida con nada, Vim salta el cursor de regreso a donde estabas cuando empezaste.
  2. : configura hlsearch ... esto le indica a Vim que muestre un fondo resaltado en todo el texto que coincida con la búsqueda de RE actual.

La otra es usar una herramienta gratuita llamada RegExCoach . Usted pega el texto que desea buscar y luego, en otra ventana, desarrolla su expresión regular. Al igual que Vim, destaca los partidos exitosos sobre la marcha.

    
respondido por el Firstrock 22.09.2011 - 20:59
2

Comienzas con una comparación básica de cadenas. Muy fácil, pero tampoco tan poderoso.

A continuación, puede que se te haya ocurrido que necesitas comparaciones insensibles a las 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, notará que las pequeñas diferencias en la ortografía no deberían impedir 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 estás feliz.

Hasta que te abstraigas un poco más y te des cuenta de que a veces quieres que todas las palabras que terminan en "ize" se comparen de la misma manera que sus hermanos en la ortografía británica. O, repeticiones de algunas cuerdas una cierta cantidad de veces. Y, por supuesto, debes combinar todo eso.

Y así sucesivamente. 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. Se puede ver 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 se destacan por sí mismos, clases de caracteres, abreviaturas útiles y no tan útiles para clases de caracteres como \ d o \ p {Lu} para las letras en mayúsculas.

Y luego, tienes 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 puedas buscar cuando la necesites.

    
respondido por el Ingo 22.09.2011 - 13:17
2

Otras dos buenas respuestas te dicen que aprendas la teoría detrás de las expresiones regulares y que practiques, que son consejos muy buenos. También recomendaría obtener una buena herramienta de expresión regular visual que te ayude si eres 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 puntos destacados y texto explicativo lo que hace el motor de expresiones regulares en cada paso. Hay un video que muestra esta depuración en su sitio.

    
respondido por el Steven 22.09.2011 - 19:03
2

Todo lo que podemos darte es más recursos para aprender. Esta pregunta es en sí misma un recurso.

Por cierto, he aprendido expresiones regulares con bastante facilidad desde este sitio: enlace

    
respondido por el Thiago Negri 22.09.2011 - 21:40
1

Para mí, ver lo que hace coincidir la expresión regular mientras estoy construyendo realmente ayuda a que mi vida sea más fácil y me ha ayudado a entenderlos mejor.

Para hacer esto, abriré un archivo con el texto de destino en Emacs y luego usaré el comando isearch-forward-regexp . Cuando ingresas a la expresión regular, Emacs te muestra qué es lo que hace coincidir (esa es la parte "isearch").

Para ejecutar el comando, en Emacs, puedes usar <ESC>xisearch-forward-regexp .

    
respondido por el jwernerny 22.09.2011 - 22:38
1

Aprendí expresiones regulares al aprender flex y bison, que se usan para construir analizadores y analizadores léxicos. No podría tener un analizador sin expresiones regulares, y el libro lexx and yacc es increíblemente bueno para caminar por el Teoría sin moverse demasiado rápido.

Fundamentalmente, prácticamente todos los motores de expresiones regulares en estos días siguen los mismos principios. Todas son máquinas de estados finitos y si realmente lo asimila, entonces tiene una ventaja sobre casi cualquier código que escriba. Es similar a aprender la recursión en que, una vez que lo obtienes, lo aplicas a los problemas de manera instintiva. Son fáciles de resolver con la herramienta correcta, pero muy difícil sin ella.

Otra cosa sobre el aprendizaje de lexx y yacc, en comparación con las expresiones regulares, es que aprendes cómo funcionan internamente. Cómo mira el programa hacia adelante, por qué termina una coincidencia, cómo guarda los datos y mucho más. Comprender los punteros es una necesidad absoluta, pero si obtienes lexx y yacc, y lo repasas desde el principio, aprenderás todo lo que pediste y tendrás una herramienta poderosamente poderosa para el resto de tu carrera.

Esta pregunta incluye un montón de recursos para el aprendizaje y un esqueleto flexible que junté.

    
respondido por el Spencer Rathbun 23.05.2017 - 14:40
1

Además, primero trato de asegurarme de que no haya una manera más fácil de resolver el problema / "tokenize" la cadena.

Cuando no puedes encontrar uno, lo veo como un problema, no por tratar de hacer coincidir lo que quieres con la cadena, sino que es cuestión de NO coincidir con lo que no quieres. Esto es principalmente porque los regex son codiciosos. Pero me ha servido como un enfoque para obtener lo que quiero.

Aquí hay un ejemplo:

string = "Sep 22 19:57:38 host fcron[9137]: \
          Job fbsetbg -r $HOME/backgrounds/ \
          started for user user (pid 9138)"

para coincidir con el minuto:

string.match /^\w+\s\d+\s\d+:(\d+):\d+\s\w+\s/ # correct but bad
string.match /\d+:([^:]+):\d+/                 # correct and good

En lugar de tratar de encontrar el tiempo junto con todo lo demás, trata de encontrar los distintos límites.

El ejemplo es un poco artificial, pero todo lo que pude encontrar.

    
respondido por el frogstarr78 23.09.2011 - 05:18
1

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 estaba compuesto de muchas expresiones regulares.

La secuencia de comandos debe ejecutarse en muchos archivos diferentes en cada proyecto de código abierto. Entonces corre contra muchos proyectos diferentes con estilos diferentes. Comencé con algo muy simple como %s/before/after y luego encontré que coincidía con demasiados 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

  • grandes habilidades y conocimientos sobre expresiones regulares
  • buenas habilidades con sed
  • ayudar a muchos proyectos de código abierto
  • obteniendo mucha actividad de contribución mostrada en mi perfil de github
  • otra buena herramienta 'swiss-army knife' para el cinturón de herramientas virtual

y fue ayudado en este enfoque por la necesidad de

  • lograr metas reales sin hacer trampa
  • use las habilidades (expresiones regulares) como parte de un objetivo mayor con mayor motivación.
  • ser capaz de mostrar pruebas de las habilidades que aprendí al cambiar el código de otros y luego revisar los cambios.

También les diré que hay un montón de sitios para los distintos idiomas, ruby, javascript, etc. que te permitirán jugar con expresiones y texto de muestra para una gratificación inmediata. Estos son:

expresiones regulares en varios idiomas en un sitio

  • enlace javascript / php / python
  • enlace PHP / JAVA / JS / ASP / .NET / C # / VB.NET

centrarse en los grupos de partido:

respondido por el Michael Durrant 18.04.2014 - 01:28
0

Descubrí que el aprendizaje de expresiones regulares es similar al aprendizaje de las tablas de multiplicar. Sí, necesitas entender las ideas que hay detrás, pero en última instancia, solo debes hacerlo con frecuencia y repetidamente.

Cuando estaba aprendiendo, me propuse la meta de hacer algunos ejercicios de expresiones regulares por día. En la práctica, esto significaba que al menos una vez al día, intentaría ver una cadena o texto en mi pantalla y encontrar un desafío: "¿puedo sacar todas las direcciones de correo electrónico de aquí" o "encontrar todas las las apariciones de la palabra 'código' se usan como verbo en lugar de como sustantivo, "cosas por el estilo".

Hacer eso durante unas pocas semanas realmente valió la pena, y por supuesto, se necesitan revisiones y actualizaciones periódicas. Estoy a punto de recibir una.

También encontré útil esta herramienta en línea, ya que me permite probar expresiones regulares en tiempo real: enlace

    
respondido por el Philip Schweiger 23.09.2011 - 03:09

Lea otras preguntas en las etiquetas