¿Por qué las expresiones regulares son tan morbosamente atractivas?


23

Anexo 1 , Anexo 2 , supongo que no le resultará difícil recordar otros ejemplos.

La cuestión es: si hay más de una forma de resolver un problema, el programador de PHP (generalmente busco la etiqueta PHP en StackOverflow) solicitará ayuda sobre la solución que involucra expresiones regulares.

Incluso cuando será menos económico, incluso cuando el manual de php sugiere ( enlace ) usar en str_replacelugar de cualquiera preg_*o ereg_*función cuando no se requieren reglas de sustitución sofisticadas.

¿Alguien tiene idea de por qué sucede esto?

No me malinterpreten, algunos de mis mejores amigos son expresiones regulares y no desprecio a Perl. Lo que no entiendo es por qué no se buscan alternativas, incluso cuando la exageración es obvia (expresión regular para cambiar las cadenas) o la complejidad del código aumenta exponencialmente (expresión regular para obtener datos de html en PHP )


2
Es posible que desee citar lo que realmente dice el manual de php.
ChrisF

1
Debido a que son crípticos, ¿quieres ser parte del exclusivo club de kewl kidz? Y sobre todo porque proporcionan una forma corta de expresar una coincidencia o extracción, para eso están hechas. Seguro para casos ficticios, el análisis personalizado es mejor, pero el tiempo de desarrollo después de escribir una expresión regular rápida está a favor de la expresión regular.
haylem

Usted enfatizó la parte incorrecta de esa última oración: la parte escandalosa es "de html", no "en PHP".
Izkata

Respuestas:


20

¿Por qué las expresiones regulares son tan morbosamente atractivas?

Porque en el nivel subconsciente se sienten como un programa inteligente completo que puede lograr mucho por sí mismo mientras se abarca y se ajusta a sí mismo (patrones de pensamiento).

Esta es la razón por la cual las personas creen de inmediato que las expresiones regulares resolverán cualquiera de sus tareas basadas en texto, de alguna manera no piensan que podría ser excesivo y no se dan cuenta de que podría ser insuficiente (analizar los idiomas con él).

Una pequeña cosa que contiene poder mágico. No puedes decir que no, ¿verdad?


55
+1 - Una pequeña cosa críptica , nada menos.
AJ Johnson

Los hobitses son engañosos
Ben DeMott

49

Cuando la única herramienta que tienes es una expresión regular, cada problema parece ^((?>[a-zA-Z\d!#$%&'*+\-/=?^_{|}~]+\x20*|"((?=[\x01-\x7f])[^"\\]|\\[\x01-\x7f])*"\x20*)*(?<angle><))?((?!\.)(?>\.?[a-zA-Z\d!#$%&'*+\-/=?^_{|}~]+)+|"((?=[\x01-\x7f])[^"\\]|\\[\x01-\x7f])*")@(((?!-)[a-zA-Z\d\-]+(?<!-)\.)+[a-zA-Z]{2,}|\[(((?(?<!\[)\.)(25[0-5]|2[0-4]\d|[01]?\d?\d)){4}|[a-zA-Z\d\-]*[a-zA-Z\d]:((?=[\x01-\x7f])[^\\\[\]]|\\[\x01-\x7f])+)\])(?(angle)>)$


16
La tentación de elegir esta respuesta es muy fuerte, pero creo que debo resistirme ya que es mi primera pregunta abierta aquí y tengo que fingir seriedad por un tiempo.
cbrandolino

1
@Dev, tiene mucho sentido. Mi comentario fue una forma supuestamente divertida de expresar mi agradecimiento por la respuesta.
cbrandolino

17
¿Qué demonios coincide con esto?
Tom O'Connor

44
No sé ... creo que esto resume todo el asunto. Si conoces expresiones regulares y no conoces los otros métodos, ¿por qué irías a buscar? Ya tienes una herramienta que, si se hace correctamente, manejará el trabajo. Hasta que se encuentren con el método más simple o se les informe sobre ello, la expresión regular será el método general, incluso si es más complejo de lo necesario.
Aeo

44
@ Tom O'Connor Creo que es algo similar a Regex para que coincida con una dirección de correo electrónico RFC 2822, pero tuve que eliminar un par de caracteres porque estaban causando estragos en la rebaja.
glenatron

23

Creo que es porque:

  1. Son fantásticamente concisos (cuando se usan correctamente) en comparación con el código equivalente, y
  2. Son ampliamente compatibles con los lenguajes de programación, por lo que la mayoría de los desarrolladores están familiarizados con ellos.

3
# 2 tiene sentido.
cbrandolino

23

En fases anteriores de mi carrera (es decir, pre-PHP), yo era un gurú de Perl, y un aspecto importante del gurudom de Perl es el dominio de las expresiones regulares.

En mi equipo actual, soy literalmente el único de nosotros que busca expresiones regulares antes que otras herramientas (generalmente más desagradables). Parece que para el resto del equipo son pura magia. Se acercarán a mi escritorio y pedirán una expresión regular que me tome literalmente diez segundos para armar, y luego quedarán impresionados cuando funcione. No lo sé, he trabajado con ellos tanto tiempo, es natural en este punto.

En ausencia de fluidez regex, te quedan combinaciones de instrucciones de control de flujo que envuelven las instrucciones strstr y strpos, lo que se vuelve feo y difícil de ejecutar en tu cabeza. Prefiero crear una elegante expresión regular que treinta líneas de búsqueda de cadenas.


2
No puedo votar esto lo suficiente.
CaffGeek

8
Tengo curiosidad: ¿ lees expresiones regulares tan fluidamente como las escribes?
Peterter

77
Espero que tengas sesiones regulares de entrenamiento de expresiones regulares y / o que documentas tu código; de lo contrario, está creando una pesadilla de apoyo para sus compañeros de trabajo. El tiempo que ahorró al escribir esa expresión regular puede perderse cientos de veces por las personas que intentan dar sentido a lo que está haciendo esa "expresión elegante".
Jeff Knecht

3
Tan estupendo. Puedes escuchar el tira y afloja entre amar y odiar expresiones regulares aquí en estos comentarios.
Dan Ray

1
@Ben Lee: Supongo que sí, OTOH, nunca me he encontrado con una expresión regular comentada en la naturaleza. Algunos de los problemas con las expresiones regulares pueden estar basados ​​en una actitud de frialdad.
peterchen

16

De lo contrario. Las personas están repitiendo que las expresiones regulares son memes malvados con demasiada frecuencia en la OMI. Es obvio que preg_match se usa en exceso php, pero es menos obvio que a menudo es sensato hacerlo (en PHP).

Llegaría tan lejos y conjeturaría que es otra microoptimización en php land para usar las funciones de cadena. Hay muchos y muchos útiles, y generalmente son la mejor opción. Pero no debes rehuir preg_matcha favor de múltiples strposy ifcadenas. Porque en la práctica resulta que libpcre es a menudo más rápido de lo que PHP puede ejecutar un ciclo buscando alternativas de cadenas, por ejemplo

Como un ejemplo reciente me hizo darme cuenta, probando si una cadena está en minúsculas:

 if ($string == strtolower($string))

Es más fácil de leer que:

 if (!preg_match("/[A-Z]/", $string))

Y asumirías que el primero debe ser más rápido, ya que es todo PHP. Pero en realidad, la expresión regular solo mira sobre la cadena una vez, y puede abortar la condición negada tan pronto como encuentra una letra mayúscula. Sin embargo, el enfoque strtolower () mira dos veces la cadena. Primero strtolower () hace una cadena duplicada iterando sobre cada letra, comparándola y mayúscula. Luego, ==itera sobre el original y la copia nuevamente, comparándolos una vez más.

Entonces ese no es un caso obvio. Y para ser objetivo, el primero suele ser más rápido, ya que normalmente solo compara cadenas cortas. Pero es imperativo no ir ciegamente suponiendo que las funciones de cadena PHP siempre son recomendables sobre las expresiones regulares.

(Estoy tentado de agregar otra queja sobre la divertida respuesta de @bobince con respecto a xhtml-regexes, y cómo recientemente a menudo se vincula de una manera muy inútil. Y las respuestas más objetivas a continuación se ignoran).


1
Estoy de acuerdo con tu ejemplo; Aún así, en este caso particular, preferiría 'strtolower ()' de todos modos: en un código no crítico, incluso una optimización de tiempo de ejecución tan grande (relativamente a la otra implementación) es insignificante, a menos que desee evaluar las minúsculas. El tamaño de un archivo de texto enorme, pero no puedo imaginar un caso en el que sería útil.
cbrandolino

1
@cbrandolino: No hay discusión allí. Estas cosas solo deberían ser relevantes y evaluadas para bucles anidados, donde podría hacer una diferencia objetiva.
mario

44
+1 Por el hecho de que las personas siempre los critican, mucho más de lo que son compatibles.
Orbling

1
Como uno de los "regexp bashers": Es divertido ver que una línea expresa más o menos para qué el análisis de cadena "manual" necesita 30 líneas. Sin embargo, el mantenimiento sufre en los ejemplos más realistas. Además, cuando se trata de aplicarlos a entradas no validadas, generar diagnósticos adecuados para entradas rechazadas requiere acrobacias adicionales. Para mí, es el código prototípico de "solo escritura" - genial para scripts rápidos, apesta para aplicaciones de larga duración.
Peterter

1
Cualquier persona que no esté escribiendo todas sus expresiones regulares en /xmodo para permitir espacios en blanco para el codo de fragmentación cognitiva, y para comentarios que expliquen por qué se están haciendo las cosas, por supuesto, debe tener los oídos tapados. Pero para expresiones regulares reales de complejidad razonable, debe considerar aplicar un diseño de arriba hacia abajo a través de expresiones regulares gramaticales . Una vez que haya visto la luz, nunca volverá a /@#$^^@#$^&&*)@#/.
tchrist

8

Las expresiones regulares son muy atractivas porque son la mejor herramienta para analizar un lenguaje regular.

Tienen las siguientes ventajas:

  • Son concisos . Por lo general, se necesita mucho más código para analizar un lenguaje regular específico utilizando un algoritmo específico que se le ocurrió que con una expresión regular.
  • Son rápidos de usar. Por lo general, lleva mucho más tiempo escribir un analizador sintáctico para un idioma regular específico utilizando un algoritmo específico que se le ocurrió que con una expresión regular.
  • Son fáciles . Una vez que aprende el conjunto de caracteres especiales y sus significados, es fácil componer una expresión regular (aunque un poco más difícil de leer). Las expresiones regulares son lenguas en sí mismas, un rasgo útil porque nuestra especie ha evolucionado para ser muy buena en el lenguaje.
  • Son rápida . Una vez compilados, pueden coincidir con una longitud de cadena Nen tiempo O ( N).
  • Son flexibles . Pueden coincidir con cualquier idioma normal y muchos de nuestros datos se expresan como un idioma normal.
  • Son ubicuos . La mayoría de los lenguajes de programación tienen soporte básico de expresiones regulares, ya sea a través de bibliotecas externas o incrustadas en el lenguaje mismo. Tampoco hay demasiada variación entre los lenguajes regexp.

Esto los hace atractivos para situaciones a las que se adaptan, pero las personas pueden usarlos en contextos donde no son la mejor herramienta, porque ellos:

  • No entiendo que lo que coinciden no se puede expresar utilizando una expresión regular (por ejemplo, HTML).
  • Son flojos (en el mal sentido): conocen una herramienta y reconocen que no es la mejor herramienta para lo que están haciendo, pero funcionará sin problemas el 95% del tiempo y requiere el 95% del esfuerzo de aprender un determinado analizador o escribir uno desde cero.
  • No saben que existen mejores herramientas.

Er, me refería a algunos casos particulares en los que evidentemente no son la mejor manera de proceder, pero todavía se usan. Me gusta la expresión regular (quiero decir, los encuentro aburridos y sin vida, pero aún así son muy útiles en algunos contextos), y sé cuáles son sus ventajas.
cbrandolino

Estoy de acuerdo con el resto, pero ¿rápido y fácil? La curva de aprendizaje es empinada: para un principiante, es difícil entender por qué una expresión no funciona, y cada implementación de expresiones regulares parece tener al menos diferencias sutiles, por lo que debe tener cuidado de dónde intenta aprender.
Peterter

¿Por qué todo el mundo confunde extraer pequeños trozos de HTML con analizar completamente una página web completa en un árbol de análisis completo? Es realmente estupido. Créeme, cuando edito páginas HTML vi, apuesto tu vida a que lo uso :%s/foo/bar/gc. Si es lo suficientemente bueno para un editor, es lo suficientemente bueno para un script.
tchrist

6

Hmmm, solo puedo adivinar. Tal vez algunas personas hayan experimentado que 30 líneas de su código fueron reemplazadas por una expresión regular de 20 caracteres de longitud, por lo que les parece incorrecto usar cualquier otra cosa cuando se pueden utilizar expresiones regulares.


4

Se ajusta a cómo piensan algunas personas. No me gustan, pero tengo amigos que parecen pensar en expresiones regulares. Supongo que la parte de coincidencia de patrones de su cerebro está más expuesta que la lógica formal. :-)


66
En términos de nuestra historia evolutiva, eso es lógico. Estábamos haciendo coincidir patrones mucho antes de definir gramáticas o descubrir silogismos.
glenatron

1
No estoy de acuerdo, la programación implica lógica y coincidencia de patrones, dos áreas. Las expresiones regulares son muy buenas para la coincidencia de patrones y deben usarse para tales tareas. Demasiado decir "No me gustan", es tirar una buena herramienta para un trabajo en particular.
Orbling

@Orbling: La pregunta no es si son buenas o malas, sino por qué algunas personas las usan en exceso y otras no.
Lennart Regebro

La pregunta puede ser, pero su respuesta sugiere que uno u otro tipo de mente está en juego, en lugar de ambos.
Orbling

No creo que "sugerir" sea la palabra correcta.
Lennart Regebro

3

Creo que la ubicuidad de la expresión regular se debe a la ubicuidad de las cadenas. La cadena es la estructura de datos más simple, la primera que la mayoría de nosotros aprendemos. Dado que todo nuestro código está escrito en forma simbólica, es natural que un programador considere modelar algo en forma simbólica. Pero si nuestro lenguaje de programación ofrece resistencia cuando intentamos extender su sintaxis para nuestras nuevas formas simbólicas inteligentes, todas terminan entre comillas. El modelo de datos relacionales tiene SQL. El modelo de datos XML tiene XQuery. Pero, ¿qué pasa con el humilde modelo de datos de cadena? Regex!

Justo ayer, estaba buscando en la API un nuevo y brillante marco de Javascript que admita el desarrollo de juegos HTML5. Tiene un mecanismo declarativo para describir los principales subsistemas que tu juego necesitaría. ¿Cómo se especifican esas características? JSON? ¿Notación de puntos fluida? ¿Una matriz? No: una cadena que contiene una lista de nombres de entidades separados por comas y espacios en blanco. Me pregunto cómo analiza esa lista ...?


2

Porque puedes ver todo de una vez. Al poder ver todo esto, puede ser más fácil trabajar con él, y eso siempre es bueno. Es como la razón por la que muchos programadores de C ++ todavía usan declaraciones tipo printf: no es seguro (aunque al menos gcc puede verificar los tipos en las declaraciones printf), y no es bonito, pero chico, es compacto y utilizable.

Si se trata de una expresión regular lo suficientemente simple, entonces a menudo SON la mejor manera de hacer las cosas: su forma compacta y muchas capacidades las hacen perfectas para ciertas tareas. El problema surge cuando hace que la expresión regular sea tan complicada que ya no puede leerla, o cuando usa una expresión regular compleja para hacer algo que podría hacerse más rápidamente mediante simples operaciones de cadena.

Regex, como cualquier otra herramienta poderosa, debe usarse con la moderación adecuada, ni demasiado ni muy poco. Y a menos que el rendimiento sea una gran preocupación, una sola expresión regular a veces puede ser más rápida de escribir y más fácil de depurar que una serie de operaciones de cadena.


2

Hmm, las respuestas actuales se centran demasiado en aspectos técnicos y los pros / contras de legibilidad (que es un punto importante). Así que déjame intentar cambiarlo un poco más en el entorno / comunidad PHP:

  • PHP es la pequeña hermanastra de Perls . Y una parte integral de Perl son expresiones regulares (inventaron esas cosas, ¿no?). Por lo tanto, es una de las razones por las cuales las expresiones regulares son dominantes en PHP también.
  • El caso de uso de PHP, por coincidencia, no es muy diferente del caso de uso para expresiones regulares. PHP se utiliza estructuralmente para pegar páginas HTML. Y las expresiones regulares funcionan en el texto. (lo que dijo WReach)
  • Micro optimización . Como se mencionó anteriormente: las personas usan expresiones regulares y / o funciones de cadena PHP con frecuencia después de la velocidad percibida. Un problema central en los círculos de PHP, no específico de expresiones regulares.
  • Las expresiones regulares están integradas . ¿En Python, en Java, en C #, en Ruby? hay disponibilidad, pero es un elemento disuasorio al tener que cargar un módulo adicional. Y vea cómo en PHP o Javascript, donde es una característica central, el patrón de uso difiere. Otra exhibición: CSS donde se usa con más frecuencia.
  • El manual de PHP tiene la culpa. A menudo lo es. Las expresiones regulares son fácilmente detectables, y pospuse este hecho divertido porque es aburrido en su obviedad: todos los malditos tutoriales y libros de introducción de PHP siempre enseñan sobre expresiones regulares, pero no educan en casos de uso.
  • La cadena de API en PHP fue diseñada por las mismas personas que le trajeron citas mágicas y el espacio de nombres \ separador. Es abarcador, mejor que Java, pero no glamoroso en su totalidad. Particularmente si las cadenas pueden duplicarse como objetos (ver Python), las funciones de cadena podrían superar las expresiones regulares.

Pero eso solo como notas al margen. Creo que, de todos modos, la mayoría de las razones técnicas y perceptivas conducen al uso excesivo y / o eludir las expresiones regulares en general. Sin embargo, PHP y su base de usuarios tienen algunas propiedades que lo componen, y por qué vemos más preguntas sobre SO al respecto [cita requerida] y son "morbosamente atractivos" allí.


1

Me gustan las expresiones regulares en general, las encuentro más fáciles de leer / comprender que las 20 líneas de código con las que tendría que reemplazarlas. Las expresiones regulares cortas se leen y entienden rápidamente y son relativamente fáciles de mantener (si la expresión cambia, solo tiene una línea para cambiar en lugar de mirar a través de las 20 líneas de código para realizar el cambio). Hay momentos en que se usan mal, pero también lo son muchas otras cosas.

La razón por la que probablemente vea tanto abuso de ellos es porque está navegando en la sección PHP de StackOverFlow, ya que estoy seguro de que sabe que hay muchos programadores PHP inmaduros.


1

¿Por qué las expresiones regulares son tan morbosamente atractivas?

Ellos no están. En realidad son feos como el infierno. E incomprensible. Son una abominación que debería ser asesinada lo antes posible.

Ahora, dicho esto, volveré a depurar una pequeña aplicación de Perl. No puedo evitarlo desafortunadamente, siguen siendo la mejor herramienta para el trabajo a veces.


44
Soy aficionado a decir que las expresiones regulares no son "regulares" ni "expresivas"
Andrew Barber

2
Son feos e incomprensibles si no los entiendes. Una vez que alcanzas el zen de regex, son realmente muy elegantes.
Dan Ray

1
-1 Por decidir que a todos los programadores les gusta ser oscuros, y luego no considerar ninguna otra explicación posible. ... Afirmar por qué crees que son feos o incomprensibles habría ayudado.
Macneil

1
@Macneil - Por favor, (aunque sí, mis pensamientos están en esa línea), a menos que me estés citando, no digas que dije / decidí algo que no hice (la primera parte de tu comentario). En cuanto a tu pregunta, ¿los encuentras hermosos? ... Yo no. Y dado que este es un sitio subjetivo, y esa es una opinión subjetiva, no tengo ni deseo desarrollarlo. Tampoco lo intentaré, para el caso.
Graok

1
@Rook: creo que la mayoría de la gente mira una expresión regular compleja, decide que todas las expresiones regulares son feas y luego deja de pensar. El hecho es que son una herramienta muy elegante y expresiva si puedes establecer tu prejuicio sobre ellos. Por cierto, según su propia lógica, muchos programadores no pueden hacer álgebra, por lo que el álgebra es probablemente inherentemente malvado y debería abolirse, ya que claramente no es muy comprensible.
Dan Ray

0

El hombre es una criatura que usa herramientas, y las expresiones regulares son herramientas poderosas. Una buena metáfora para las expresiones regulares es una cortadora de carne de una tienda de delicatessen. Si desea rebanadas finas como el papel de pavo, carne en conserva, etc., es justo lo que necesita. Sin embargo, necesita manos hábiles para usarlo, porque puede cortarse muy mal con él y no sentirá nada hasta que vea la sangre. Lo que quiero decir con esto es que el gran problema con las expresiones regulares es que las quita un poco, significa que coincide con algo que no debería, o viceversa, y no se entera hasta que causa un problema más adelante en el proceso.


0

Las expresiones regulares son muy atractivas porque ejercen poder. Puedes hacer un trabajo muy complicado en muy pocos personajes.

El problema es que la construcción de expresión regular estándar no es completa de Turing, lo que significa que hay programas que simplemente no puede implementar con una expresión regular, y las personas no SABEN eso cuando se sienten atraídos por el aparente poder de las expresiones regulares.

Esto, supongo, es la razón de la cita jwz de "ahora tienen dos problemas".

Me supongo que Perl expresiones regulares son Turing completo, pero al parecer no ha sido decisiva probar o refutar todavía.


0

Porque es una manera eficiente de programar una máquina de estados finitos, que es una herramienta poderosa cuando se aplica. Básicamente es su propio lenguaje para programar FSM, lo cual es útil si conoce el idioma, molesto si no lo sabe.


0

En mi experiencia, las expresiones regulares son como un arte antiguo, algo oscuro, algunas personas se molestan porque no pueden entender la brujería involucrada y tal vez porque nadie te las explicará. No he oído hablar de universidades que les enseñen por algo menos trivial que hacer coincidir un correo electrónico. Luego está el funcionamiento interno místico, ya que la mayoría de la gente no los entiende, deben ser lentos . Y lograr que funcionen bien en el primer intento siempre es un desafío para los recién llegados.

Lo mismo puede decirse de Perl, awk, Linux y todo lo que no tiene botones brillantes o una sintaxis de color agradable. Por lo tanto, es como una complejidad adicional para las "tareas triviales", simplemente lanzar algunos bucles, divisiones, un interruptor, algo de magia y eso es todo, algo que podría funcionar. Pero bueno, si estás al otro lado de la carretera, las expresiones regulares son hermosos cortadores de galletas que parecen ruido de señal sin bucles desagradables o más cosas para depurar. También me gustan por la flexibilidad que brindan. Cuando cambia el patrón para que coincida, simplemente cambia la expresión regular, no el algoritmo, o la herramienta / lo que sea, y es agradable y funciona de nuevo. Y dado que son una cadena mágica, puede colocarla fuera del código fuente si lo desea. Y otra cosa que me hace pensar en Perl, si escribes una expresión regular de más de 20 caracteres, siento que has logrado mucho, Al menos para mí, es tan ordenado y compacto. También soy un programador perezoso, no me gusta escribir mucho código con buenas ideas y comentarios y agregar algunos errores a la mezcla.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.