¿Por qué las expresiones regulares son tan controvertidas? [cerrado]

212

Al explorar expresiones regulares (también conocidas como RegEx-es), hay muchas personas que parecen ver las expresiones regulares como el Santo Grial. Algo que parece tan complicado, solo debe ser la respuesta a cualquier pregunta. Tienden a pensar que cada problema se puede resolver utilizando expresiones regulares.

Por otro lado, también hay muchas personas que intentan evitar las expresiones regulares a toda costa. Intentan encontrar una forma de evitar las expresiones regulares y aceptan codificación adicional solo por el bien, incluso si una expresión regular sería una solución más compacta.

¿Por qué las expresiones regulares se consideran tan controvertidas? ¿Hay malentendidos generalizados sobre cómo funcionan? ¿O podría ser una creencia generalizada de que las expresiones regulares son generalmente lentas?

Gumbo
fuente
99
Si esto es una discusión, ¿no debería cerrarse? pero veo una pregunta real allí, ¿quizás la etiqueta de discusión no pertenezca?
RCIX
66
En serio. Lo mencionas y la gente comienza a volverse loca por aquí.
Ryan Florence
1
Buena observación y redacción en la pregunta!
imz - Ivan Zakharyaschev
La pregunta se basa en la opinión, la regla también debe aplicarse aquí (o la pregunta debe editarse para obtener una respuesta precisa). Dicho esto, supongo que regex controverse proviene de la falta de precisión de los tutoriales y manuales al respecto. La mayoría de las veces, si no todo el tiempo, la información es mixta y, además, no se nos dan todas las características. Si a eso se le falta el uso del idioma, terminará aprendiendo algo para notar en el futuro que puede significar algo más. Y, por último, los caracteres especiales de expresiones regulares no se limitan a un significado que agrega más confusión.
intika

Respuestas:

136

No creo que las personas se opongan a las expresiones regulares porque son lentas, sino porque son difíciles de leer y escribir, así como difíciles de entender. Si bien hay algunas situaciones en las que las expresiones regulares brindan una solución efectiva y compacta al problema, a veces se encuentran en situaciones en las que es mejor usar una sección de código fácil de leer y fácil de mantener.

Kyle Cronin
fuente
2
Y sí, las expresiones regulares pueden ser extremadamente lentas en comparación con el uso de funciones simples. Y no solo lento, sino que el rendimiento del motor regex puede ser totalmente impredecible cuando se enfrenta a entradas arbitrarias (proporcionadas por el usuario).
Pacerier
1
Si sabes cómo funciona la expresión regular, no es un problema en absoluto.
Shiplu Mokaddim
8
@pacerier, no son patrones lentos , son motores lentos . La mayoría de los motores de expresión regular (modernos) no son adecuados para patrones complejos (por ejemplo, muchos |o .*), porque usan una máquina de pila y retroceso. Es por eso que debe ajustar cuidadosamente sus expresiones regulares en Perl, Java, Python, Ruby ... Los motores de expresiones regulares de estilo antiguo (en grep, por ejemplo) primero compilan el patrón en un DFA. Posteriormente, la complejidad del patrón es en gran medida irrelevante. Acabo de usar Java y grep para el mismo texto y patrón: 22min vs 2s. Aquí está la ciencia: swtch.com/~rsc/regexp/regexp1.html
hagello
122

Hacer que las expresiones regulares se mantengan

Un avance importante para desmitificar los patrones anteriormente conocidos como "expresiones regulares" es la /xbandera de expresión regular de Perl, a veces escrita (?x)cuando está incrustada, que permite espacios en blanco (salto de línea, sangría) y comentarios. Esto mejora seriamente la legibilidad y, por lo tanto, la mantenibilidad. El espacio en blanco permite la fragmentación cognitiva, para que pueda ver qué grupos con qué.

Los patrones modernos ahora también admiten referencias posteriores relativamente numeradas y con nombre. Eso significa que ya no necesita contar grupos de captura para darse cuenta de que necesita $4o \7. Esto ayuda al crear patrones que se pueden incluir en otros patrones.

Aquí hay un ejemplo de un grupo de captura relativamente numerado:

$ dupword = qr {\ b (?: (\ w +) (?: \ s + \ g {-1}) +) \ b} xi;
$ entrecomillado = qr {(["']) $ dupword \ 1} x;

Y aquí hay un ejemplo del enfoque superior de las capturas con nombre:

$dupword = qr{ \b (?: (?<word> \w+ ) (?: \s+ \k<word> )+ ) \b }xi;
$quoted  = qr{ (?<quote> ["'] ) $dupword  \g{quote} }x;

Expresiones regulares gramaticales

Lo mejor de todo es que estas capturas con nombre se pueden colocar dentro de un (?(DEFINE)...)bloque, para que pueda separar la declaración de la ejecución de elementos con nombre individuales de sus patrones. Esto los hace actuar más bien como subrutinas dentro del patrón.
Un buen ejemplo de este tipo de "expresión gramatical" se puede encontrar en esta respuesta y en esta . Estos se parecen mucho más a una declaración gramatical.

Como este último te recuerda:

… Asegúrese de nunca escribir patrones de ruido de línea. No tienes que hacerlo, y no deberías. No se puede mantener ningún lenguaje de programación que prohíba espacios en blanco, comentarios, subrutinas o identificadores alfanuméricos. Así que usa todas esas cosas en tus patrones.

Esto no puede ser sobre enfatizado. Por supuesto, si no usa esas cosas en sus patrones, a menudo creará una pesadilla. Pero si haces uso de ellos, sin embargo, no es necesario.

Aquí hay otro ejemplo de un patrón gramatical moderno, este para analizar RFC 5322: use 5.10.0;

$rfc5322 = qr{

   (?(DEFINE)

     (?<address>         (?&mailbox) | (?&group))
     (?<mailbox>         (?&name_addr) | (?&addr_spec))
     (?<name_addr>       (?&display_name)? (?&angle_addr))
     (?<angle_addr>      (?&CFWS)? < (?&addr_spec) > (?&CFWS)?)
     (?<group>           (?&display_name) : (?:(?&mailbox_list) | (?&CFWS))? ; (?&CFWS)?)
     (?<display_name>    (?&phrase))
     (?<mailbox_list>    (?&mailbox) (?: , (?&mailbox))*)

     (?<addr_spec>       (?&local_part) \@ (?&domain))
     (?<local_part>      (?&dot_atom) | (?&quoted_string))
     (?<domain>          (?&dot_atom) | (?&domain_literal))
     (?<domain_literal>  (?&CFWS)? \[ (?: (?&FWS)? (?&dcontent))* (?&FWS)?
                                   \] (?&CFWS)?)
     (?<dcontent>        (?&dtext) | (?&quoted_pair))
     (?<dtext>           (?&NO_WS_CTL) | [\x21-\x5a\x5e-\x7e])

     (?<atext>           (?&ALPHA) | (?&DIGIT) | [!#\$%&'*+-/=?^_`{|}~])
     (?<atom>            (?&CFWS)? (?&atext)+ (?&CFWS)?)
     (?<dot_atom>        (?&CFWS)? (?&dot_atom_text) (?&CFWS)?)
     (?<dot_atom_text>   (?&atext)+ (?: \. (?&atext)+)*)

     (?<text>            [\x01-\x09\x0b\x0c\x0e-\x7f])
     (?<quoted_pair>     \\ (?&text))

     (?<qtext>           (?&NO_WS_CTL) | [\x21\x23-\x5b\x5d-\x7e])
     (?<qcontent>        (?&qtext) | (?&quoted_pair))
     (?<quoted_string>   (?&CFWS)? (?&DQUOTE) (?:(?&FWS)? (?&qcontent))*
                          (?&FWS)? (?&DQUOTE) (?&CFWS)?)

     (?<word>            (?&atom) | (?&quoted_string))
     (?<phrase>          (?&word)+)

     # Folding white space
     (?<FWS>             (?: (?&WSP)* (?&CRLF))? (?&WSP)+)
     (?<ctext>           (?&NO_WS_CTL) | [\x21-\x27\x2a-\x5b\x5d-\x7e])
     (?<ccontent>        (?&ctext) | (?&quoted_pair) | (?&comment))
     (?<comment>         \( (?: (?&FWS)? (?&ccontent))* (?&FWS)? \) )
     (?<CFWS>            (?: (?&FWS)? (?&comment))*
                         (?: (?:(?&FWS)? (?&comment)) | (?&FWS)))

     # No whitespace control
     (?<NO_WS_CTL>       [\x01-\x08\x0b\x0c\x0e-\x1f\x7f])

     (?<ALPHA>           [A-Za-z])
     (?<DIGIT>           [0-9])
     (?<CRLF>            \x0d \x0a)
     (?<DQUOTE>          ")
     (?<WSP>             [\x20\x09])
   )

   (?&address)

}x;

¿No es eso notable y espléndido? ¡Puede tomar una gramática de estilo BNF y traducirla directamente a código sin perder su estructura fundamental!

Si los patrones gramaticales modernos aún no son suficientes para usted, entonces el brillante Regexp::Grammarsmódulo de Damian Conway ofrece una sintaxis aún más limpia, con una depuración superior también. Aquí está el mismo código para analizar RFC 5322 refundido en un patrón de ese módulo:

#!/usr/bin/perl

use strict;
use warnings;
use 5.010;
use Data::Dumper "Dumper";

my $rfc5322 = do {
    use Regexp::Grammars;    # ...the magic is lexically scoped
    qr{

    # Keep the big stick handy, just in case...
    # <debug:on>

    # Match this...
    <address>

    # As defined by these...
    <token: address>         <mailbox> | <group>
    <token: mailbox>         <name_addr> | <addr_spec>
    <token: name_addr>       <display_name>? <angle_addr>
    <token: angle_addr>      <CFWS>? \< <addr_spec> \> <CFWS>?
    <token: group>           <display_name> : (?:<mailbox_list> | <CFWS>)? ; <CFWS>?
    <token: display_name>    <phrase>
    <token: mailbox_list>    <[mailbox]> ** (,)

    <token: addr_spec>       <local_part> \@ <domain>
    <token: local_part>      <dot_atom> | <quoted_string>
    <token: domain>          <dot_atom> | <domain_literal>
    <token: domain_literal>  <CFWS>? \[ (?: <FWS>? <[dcontent]>)* <FWS>?

    <token: dcontent>        <dtext> | <quoted_pair>
    <token: dtext>           <.NO_WS_CTL> | [\x21-\x5a\x5e-\x7e]

    <token: atext>           <.ALPHA> | <.DIGIT> | [!#\$%&'*+-/=?^_`{|}~]
    <token: atom>            <.CFWS>? <.atext>+ <.CFWS>?
    <token: dot_atom>        <.CFWS>? <.dot_atom_text> <.CFWS>?
    <token: dot_atom>        <.CFWS>? <.dot_atom_text> <.CFWS>?
    <token: dot_atom_text>   <.atext>+ (?: \. <.atext>+)*

    <token: text>            [\x01-\x09\x0b\x0c\x0e-\x7f]
    <token: quoted_pair>     \\ <.text>

    <token: qtext>           <.NO_WS_CTL> | [\x21\x23-\x5b\x5d-\x7e]
    <token: qcontent>        <.qtext> | <.quoted_pair>
    <token: quoted_string>   <.CFWS>? <.DQUOTE> (?:<.FWS>? <.qcontent>)*
                             <.FWS>? <.DQUOTE> <.CFWS>?

    <token: word>            <.atom> | <.quoted_string>
    <token: phrase>          <.word>+

    # Folding white space
    <token: FWS>             (?: <.WSP>* <.CRLF>)? <.WSP>+
    <token: ctext>           <.NO_WS_CTL> | [\x21-\x27\x2a-\x5b\x5d-\x7e]
    <token: ccontent>        <.ctext> | <.quoted_pair> | <.comment>
    <token: comment>         \( (?: <.FWS>? <.ccontent>)* <.FWS>? \)
    <token: CFWS>            (?: <.FWS>? <.comment>)*
                             (?: (?:<.FWS>? <.comment>) | <.FWS>)

    # No whitespace control
    <token: NO_WS_CTL>       [\x01-\x08\x0b\x0c\x0e-\x1f\x7f]

    <token: ALPHA>           [A-Za-z]
    <token: DIGIT>           [0-9]
    <token: CRLF>            \x0d \x0a
    <token: DQUOTE>          "
    <token: WSP>             [\x20\x09]

    }x;

};


while (my $input = <>) {
    if ($input =~ $rfc5322) {
        say Dumper \%/;       # ...the parse tree of any successful match
                              # appears in this punctuation variable
    }
}

Hay un montón de cosas buenas en la perlre página de manual , pero estas mejoras en las características de diseño de expresiones regulares son fundamentales no se limita a Perl solo. De hecho la pcrepattern página de manual puede ser una lectura más fácil, y cubre el mismo territorio.

Los patrones modernos no tienen casi nada en común con las cosas primitivas que le enseñaron en su clase de autómatas finitos.

tchrist
fuente
99
¡SI! ¡SI! Finalmente, alguien muestra un gran ejemplo de cuán legibles pueden ser las expresiones regulares con el modificador x. No puedo creer cómo pocas personas saben que existe, y mucho menos usarlo.
Shabbyrobe
1
@ Shabbyrobe: no es solo /x. Es el uso de las expresiones regulares gramaticalmente, con (?&name)subrutinas de expresiones regulares internas, lo que realmente hace que brille.
tchrist
+1 Siempre aprendes algo nuevo. No sabía que PCRE tenía una condición "falsa" para definir.
NikiC
55
Python también tiene una re.VERBOSEbandera.
Caracol mecánico
3
Simplemente sigan adelante y digan que todavía estoy sorprendido de lo lejos que irán las personas para hacer que la expresión regular sea utilizable.
Slater Victoroff
68

Las expresiones regulares son una gran herramienta, pero la gente piensa "¡Oye, qué gran herramienta, la usaré para hacer X!" donde X es algo para lo que una herramienta diferente es mejor (generalmente un analizador sintáctico). Es el estándar que usa un martillo donde necesita un problema de destornillador.

Chas Owens
fuente
44
Solo recuerde que la mayoría de los analizadores -analizadores digitales- todavía usan expresiones regulares para analizar sus cosas :-)
Jasper Bekkers
62
Decir que los analizadores usan expresiones regulares es como decir que los analizadores usan declaraciones de asignación. No significa nada hasta que mires para ver cómo se están utilizando.
Chas. Owens
24
Usar un RegEx cuando un analizador es mejor es molesto. Usar un RegEx cuando las funciones estándar de búsqueda o reemplazo de cadenas del lenguaje funcionarán (y en tiempo lineal generalmente) es imperdonable.
jmucchiello
1
De acuerdo, ya que un RegEx tiene que ser un factor decisivo en todos los intercambios, su procesamiento es muy elevado. El hecho de que usar un motor RegEx parezca fácil no significa que sea una mejor solución sobre un analizador iterativo (umbral dependiente del desarrollador). Uno de mis ejemplos favoritos de PHP split($pattern,$string)vs explode($delimiter,$string): afortunadamente, el primero se está depreciando, pero muchos códigos usaron el primero cuando solo necesitaban el poder del segundo. Agregados, los RegEx proporcionan una herramienta fácil para hacer algunas cosas, pero a menos que necesite todo el poder de las expresiones regulares, ellos
Rudu
44
Los analizadores léxicos pueden usar expresiones regulares. También se conocen como tokenizadores, pero no son analizadores sintácticos (o analizadores sintácticos). Para leer una cadena lo suficientemente complicada, se debe usar un tokenizador para leer la cadena como tokens (tal vez con expresiones regulares, tal vez no, dependiendo del tokenizador). Estos tokens deberían pasarse al analizador, que los procesará con reglas gramaticales, que definitivamente no son expresiones regulares.
Axel
53

Casi todos los que conozco que usan expresiones regulares regularmente (juego de palabras) provienen de un fondo Unix-ish donde usan herramientas que tratan los RE como construcciones de programación de primera clase, como grep, sed, awk y Perl. Como casi no hay sobrecarga sintáctica para usar una expresión regular, su productividad aumenta mucho cuando lo hacen.

Por el contrario, los programadores que usan lenguajes en los que los RE son una biblioteca externa tienden a no considerar qué expresiones regulares pueden aportar a la tabla. El "costo de tiempo" del programador es tan alto que a) los RE nunca aparecieron como parte de su entrenamiento, o b) no "piensan" en términos de los RE y prefieren recurrir a patrones más familiares.

Barry Brown
fuente
11
Sí, nunca perdoné a Python por hacer que la sintaxis de expresiones regulares sea detallada usando una biblioteca. Creo que es pureza sobre cordura.
slikts
77
Vengo de un fondo Unix, utilicé cargas sed, awk y perl, y por supuesto hice un montón de grepping, pero sé que cuando uso una expresión regular, es un truco de solo escritura que odiaré mantener. Es bueno para los scripts de shell / one-timers, pero para el trabajo real, para cualquier cosa que no sea solo agarrar algunos datos para guardar ahora, ahora uso un tokenizador / lexer / parser adecuado con una sintaxis clara. Mi favorito hace todo / cualquiera, limpiamente + puede auto-optimizarse. Aprendí por las malas, y durante muchos años, que un poco de autodisciplina al principio significa menos esfuerzo más adelante. Una expresión regular es un momento en el teclado y toda una vida en el ceño fruncido.
AndrewC
44

Las expresiones regulares le permiten escribir una máquina de estados finitos (FSM) personalizada de forma compacta, para procesar una cadena de entrada. Hay al menos dos razones por las que es difícil usar expresiones regulares:

  • El desarrollo de software de la vieja escuela implica mucha planificación, modelos en papel y una cuidadosa reflexión. Las expresiones regulares se ajustan muy bien a este modelo, porque escribir una expresión efectiva correctamente implica mirarlo fijamente, visualizar los caminos del FSM.

    Los desarrolladores de software modernos preferirían forjar el código y usar un depurador para avanzar en la ejecución y ver si el código es correcto. Las expresiones regulares no admiten este estilo de trabajo muy bien. Una "ejecución" de una expresión regular es efectivamente una operación atómica. Es difícil observar la ejecución gradual en un depurador.

  • Es demasiado fácil escribir una expresión regular que accidentalmente acepte más entradas de las que pretende. El valor de una expresión regular no coincide realmente con una entrada válida, sino que no coincide con una entrada no válida . Las técnicas para hacer "pruebas negativas" para expresiones regulares no son muy avanzadas, o al menos no se usan ampliamente.

    Esto va al punto de que las expresiones regulares son difíciles de leer. Con solo mirar una expresión regular, se necesita mucha concentración para visualizar todas las entradas posibles que deberían rechazarse, pero se aceptan por error. ¿Alguna vez trató de depurar el código de expresión regular de otra persona ?

Si existe una resistencia al uso de expresiones regulares entre los desarrolladores de software hoy, creo que se debe principalmente a estos dos factores.

Bill Karwin
fuente
44
Existen excelentes herramientas para depurar expresiones regulares: regexbuddy.com
Jasper Bekkers
15
perl -Mre = debug -e "q [aabbcc] = ~ / ab * [cd] /"
Brad Gilbert el
15
No creo que pueda ver el acrónimo "FSM" sin pensar en el Flying Spaghetti Monster.
Shabbyrobe
44
@ Shabbyrobe: no quiero ofender. Si lo desea, puede utilizar el autómata finito determinista (DFA).
Bill Karwin el
37

La gente tiende a pensar que las expresiones regulares son difíciles; pero eso es porque los están usando mal. Escritura de frases complejas sin comentarios, sangría o capturas con nombre. (No abarrota su compleja expresión SQL en una línea, sin comentarios, sangría o alias, ¿verdad?). Entonces sí, para mucha gente, no tienen sentido.

Sin embargo, si su trabajo tiene algo que ver con el análisis de texto (casi cualquier aplicación web existente ...) y no conoce la expresión regular, apesta en su trabajo y está perdiendo su propio tiempo y el de su empleador. Existen excelentes recursos para enseñarle todo lo que necesitará saber sobre ellos, y más.

Jasper Bekkers
fuente
2
Bueno .. la diferencia es que múltiples espacios tienen significado en expresiones regulares, donde en otros idiomas que no lo hacen y es por eso por lo general son los trazadores de líneas (que a veces envuelve a varias líneas :)
Rado
14
@Rado: Perl, por ejemplo, tiene el xmodificador para expresiones regulares que hace que se ignore el espacio en blanco. Esto le permite poner la expresión regular en unas pocas líneas y agregar comentarios.
Nathan Fellman
99
Del mismo modo Python tiene re.Xaka re.VERBOSE.
Craig McQueen
2
Asimismo el xmodificador en tcl. Creo que es bastante estándar ya que tcl, a diferencia de otros idiomas, no usa PCRE.
slebetman
2
@AndrewC Esa es una de las malas interpretaciones más groseras que esta publicación podría haber recibido.
Jasper Bekkers
28

Debido a que carecen de la herramienta de aprendizaje más popular en los IDE comúnmente aceptados: no existe el Asistente de expresiones regulares. Ni siquiera Autocompletado. Tienes que codificar todo por ti mismo.

dkretz
fuente
3
Entonces estás usando el IDE incorrecto ... Incluso mi editor de texto proporciona pistas sobre expresiones regulares.
CurtainDog el
1
En una nota al margen, Expresso y The Regex Coach son herramientas muy útiles para construir expresiones regulares.
Mun
22
¿Cómo diablos autocompletarías una expresión regular?
AmbroseChapel
3
EditPad Pro tiene resaltado de sintaxis para expresiones regulares en el cuadro de búsqueda, pero lo encuentro más molesto que útil, y lo mantengo apagado. Pero aprecio que me avise cuando tengo paréntesis sin igual; los paréntesis en particular pueden ser un oso a seguir.
Alan Moore
2
@AmbroseChapel: llegué un par de años tarde a esta discusión. Pero creé un mecanismo de autocompletado en regexhero.net/tester. Lo inician las construcciones comunes dentro de corchetes redondos (), cuadrados []o rizados {}. También funcionará con la barra invertida.
Steve Wortham
16

No creo que sean tan controvertidos.

También creo que ha respondido su propia pregunta, porque señala lo tonto que sería usarlos en todas partes ( no todo es un lenguaje normal 2 ) o evitar usarlos en absoluto. Usted, el programador, debe tomar una decisión inteligente sobre cuándo las expresiones regulares ayudarán al código o lo dañarán. Cuando se enfrenta a tal decisión, dos cosas importantes a tener en cuenta son la capacidad de mantenimiento (que implica legibilidad) y la extensibilidad.

Para aquellos que son particularmente reacios a ellos, supongo que nunca aprendieron a usarlos adecuadamente. Creo que la mayoría de las personas que pasan unas pocas horas con un tutorial decente los descubrirán y hablarán con fluidez muy rápidamente. Aquí está mi sugerencia sobre dónde comenzar:

http://docs.python.org/howto/regex

Aunque esa página habla de expresiones regulares en el contexto de Python, he encontrado que la información es muy aplicable en otros lugares. Hay algunas cosas que son específicas de Python, pero creo que se notan claramente y son fáciles de recordar.

allyourcode
fuente
2
La página parece moverse a docs.python.org/howto/regex
Dominic K
@DMan Gracias. Editaré mi respuesta para reflexionar.
allyourcode
11

Las expresiones regulares son para cadenas lo que los operadores aritméticos son para números, y no los consideraría controvertidos. Creo que incluso un activista OO bastante militante como yo (que tendería a elegir otros objetos en lugar de cadenas) sería difícil rechazarlos.

Peter Mortensen
fuente
7

El problema es que las expresiones regulares son potencialmente tan poderosas que puedes hacer cosas con ellas para las que deberías usar algo diferente.

Un buen programador debe saber dónde usarlos y dónde no. El ejemplo típico es analizar idiomas no regulares (consulte Decidir si un idioma es regular ).

Creo que no puedes equivocarte si al principio te limitas a expresiones regulares reales (sin extensiones). Algunas extensiones pueden hacer su vida un poco más fácil, pero si encuentra algo difícil de expresar como una expresión regular real , esto puede ser una indicación de que una expresión regular no es la herramienta correcta.

Svante
fuente
5

Es muy probable que se pregunte por qué los goto son controvertidos.

Básicamente, cuando obtienes tanto poder "obvio", las personas tienden a abusar de ellos en situaciones para las que no son la mejor opción. La cantidad de personas que piden analizar CSV o XML o HTML en expresiones regulares, por ejemplo, me asombra. Es la herramienta incorrecta para el trabajo. Pero algunos usuarios insisten en usar expresiones regulares de todos modos.

Personalmente, trato de encontrar ese medio feliz: use expresiones regulares para lo que son buenas y evítelas cuando no sean óptimas.

Tenga en cuenta que las expresiones regulares todavía se pueden usar para analizar CSV, XML, HTML, etc. Pero generalmente no en una sola expresión regular.

Tanktalus
fuente
Seguro que puedes analizar cualquiera de estos formatos en una sola expresión regular, ¡ese es el poder de las expresiones regulares, bebé! Si quieres o no hacer eso, es un asunto completamente diferente.
Jasper el
4

No creo que "controvertido" sea la palabra correcta.

Pero he visto toneladas de ejemplos en los que la gente dice "¿cuál es la expresión regular que necesito para hacer tal y tal manipulación de cadenas?" que son problemas XY

En otras palabras, comenzaron desde el supuesto de que una expresión regular es lo que necesitan, pero sería mejor con una división (), una traducción como perl's tr /// donde los caracteres se sustituyen uno por el otro, o solo un índice ().

AmbroseChapel
fuente
4

Este es un tema interesante.
Muchos aficionados a expresiones regulares parecen confundir la concisión de la fórmula con la eficiencia.
Además de eso, una expresión regular que requiere mucho pensamiento produce a su autor una satisfacción masiva que lo hace legítimo de inmediato.

Pero ... las expresiones regulares son muy convenientes cuando el rendimiento no es un problema y necesita tratar rápidamente con una salida de texto, en Perl, por ejemplo. Además, si bien el rendimiento es un problema, uno puede preferir no tratar de superar la biblioteca regexp mediante el uso de un algoritmo casero que puede tener errores o ser menos eficiente.

Además, hay una serie de razones por las cuales las expresiones regulares son injustamente criticadas, por ejemplo

  • la expresión regular no es eficiente, porque construir la superior no es obvio
  • algunos programadores "olvidan" compilar solo una vez una expresión regular para usarla muchas veces (como un patrón estático en Java)
  • algunos programadores apuestan por la estrategia de prueba y error : ¡funciona aún menos con expresiones regulares!
e2-e4
fuente
4

Lo que creo es que Learning Regex y el mantenimiento de expresiones regulares no son populares, la mayoría de los desarrolladores son flojos o la mayoría de ellos confían en bibliotecas externas para que hagan el análisis por ellos ... confían en Google para obtener la respuesta e incluso preguntan en foros por El código completo para su problema. Pero cuando se trata de implementar o modificar / mantener una expresión regular, simplemente fallan.

Hay un dicho popular que dice "Los amigos no permiten que los amigos usen Regex para analizar HTML"

Pero en lo que a mí respecta, he realizado analizadores HTML completos utilizando Regex y creo que regex es mejor para analizar cadenas html tanto en velocidad como en memoria (si tienes una idea de lo que debes lograr :))

Rajeev
fuente
2
Creo que es falso descartar a la mayoría de los desarrolladores ... como vagos. Yo diría que la sintaxis es muy críptica, poco intuitiva y llena de trampas, para los no iniciados, lo que conduce a una alta barrera de entrada. Por la misma razón, Perl tiene una "mala" reputación para muchos, pero también es un lenguaje muy poderoso. Es como tratar de leer expresiones matemáticas antes de conocer los símbolos. Es desalentador, y los desarrolladores deben ser judiciales con su tiempo para saber que obtendrán beneficios por aprender esa sintaxis.
Katastic Voyage
Usted se olvida casos extremos en HTML porque HTML no es un lenguaje regular. Está seguro si su intención es analizar un subconjunto conocido de HTML
Boyang
2

Las expresiones regulares son un misterio serio para muchas personas, incluido yo mismo. Funciona muy bien, pero es como mirar una ecuación matemática. Sin embargo, me complace informar que alguien finalmente ha creado una ubicación consolidada de varias funciones de expresión regular en http://regexlib.com/ . Ahora, si Microsoft solo creara una clase de expresión regular que automáticamente hiciera muchas de las cosas comunes como eliminar letras o filtrar fechas.

Al Katawazi
fuente
2
Te estás perdiendo el punto. La idea de las expresiones regulares es que inviertas algo de tiempo en aprenderlas y cuando hayas terminado, ya no necesitarás una clase mágica de "leer una cita". En cambio, requiere muy poco esfuerzo regex para ellos. Además, tomará tan poco esfuerzo escribir uno para "aaaa / mm / dd" como escribir uno para "mm-dd-aaaa", o incluso uno para "mm-aaaa / dd" (que ganó sucede a menudo, pero es un ejemplo de cómo puedes hacer cosas que una clase de magia nunca puede hacer ").
Jasper
1

Encuentro expresiones regulares invaluables a veces. Cuando necesito hacer algunas búsquedas "difusas", y tal vez reemplaza. Cuando los datos pueden variar y tener una cierta aleatoriedad. Sin embargo, cuando necesito hacer una simple búsqueda y reemplazo, o verificar una cadena, no uso expresiones regulares. Aunque conozco a muchas personas que lo hacen, lo usan para todo. Esa es la controversia.

Si quieres poner una tachuela en la pared, no uses un martillo. Sí, funcionará, pero para cuando obtengas el martillo, podría poner 20 tachuelas en la pared.

Las expresiones regulares deben usarse para lo que fueron diseñadas, y nada menos.

Brent Baisley
fuente
0

Si bien creo que las expresiones regulares son una herramienta esencial, lo más molesto de ellas es que existen diferentes implementaciones. Las pequeñas diferencias en la sintaxis, los modificadores y, especialmente, la "codicia" pueden hacer que las cosas sean realmente caóticas, requiriendo prueba y error y, a veces, generando errores desconcertantes.

ndr
fuente
¿Cómo difieren las implementaciones de expresiones regulares en su enfoque de coincidencia máxima, lo que creo que llamamos "avaricia"? ¿Se refiere a la diferencia entre la izquierda más larga en comparación con más a la izquierda más larga semántica? Esa es la única diferencia que conozco; es decir, si la codicia triunfa sobre el entusiasmo o viceversa .
tchrist el
0

En algunos casos creo que tienes que usarlos. Por ejemplo para construir un lexer.

En mi opinión, este es un punto de vista de las personas que pueden escribir expresiones regulares y las personas que no (o apenas). Personalmente, creo que esta es una buena idea, por ejemplo, para validar la entrada de un formulario, ya sea en JavaScript para advertir al usuario, o en un lenguaje del lado del servidor.

Aif
fuente
0

Creo que es una técnica menos conocida entre los programadores. Por lo tanto, no hay una amplia aceptación para ello. Y si tiene un gerente no técnico para revisar su código o revisar su trabajo, entonces una expresión regular es muy mala. Pasará horas escribiendo una expresión regular perfecta, y obtendrá pocas marcas para el módulo pensando que él / ella ha escrito tan pocas líneas de código. Además, como se dijo en otra parte, leer expresiones regulares es una tarea muy difícil.

Satya Prakash
fuente
1
La lectura de expresiones regulares es una tarea difícil solo cuando el programador que las creó no pudo utilizar espacios en blanco, comentarios, identificadores alfanuméricos y quizás también subrutinas incrustadas a través de la ejecución retrasada. En resumen, todas las técnicas de ingeniería de software aplicables a la programación general también deben seguirse en expresiones regulares. Si se ignoran estos principios, entonces el escritor no está produciendo código profesional.
tchrist el
Creo que su gerente no sabe que "el verdadero héroe de la programación es el que escribe código negativo".
Rajeev
Si su gerente lo criticará por completar el trabajo con 3 líneas de código (incluidas las expresiones regulares), mientras elogia a un compañero de trabajo que lo hizo en 900 líneas de Assembler ... Sugiero encontrar un nuevo trabajo.
Phil Perry el
0

Los sistemas de expresión regular decentes, como los utilizados en lex y yacc para la definición del compilador, son buenos, muy útiles y limpios. En estos sistemas, los tipos de expresión se definen en términos de otros. Son las expresiones regulares horribles mal formadas, ilegibles, gigantescas, de un solo trazo, que se encuentran comúnmente en el código perl y sed (etc.) que son 'controvertidas' (basura).

Sam Watkins
fuente
-4

El mejor uso válido y normal para regex es para la validación del formato de dirección de correo electrónico.

Esa es una buena aplicación.

He usado expresiones regulares innumerables veces como únicas en TextPad para masajear archivos planos, crear archivos csv, crear declaraciones de inserción SQL y ese tipo de cosas.

Las expresiones regulares bien escritas no deberían ser demasiado lentas. Por lo general, las alternativas, como toneladas de llamadas a Reemplazar, son opciones mucho más lentas. También podría hacerlo de una sola vez.

Muchas situaciones requieren expresiones regulares y nada más.

Reemplazar caracteres especiales que no se imprimen con caracteres inocuos es otro buen uso.

Por supuesto, puedo imaginar que hay algunas bases de código que usan en exceso las expresiones regulares en detrimento de la mantenibilidad. Nunca lo he visto yo mismo. De hecho, los revisores de código me han evitado que no use suficientes expresiones regulares.

Chris Morley
fuente
10
La experiencia muestra que las expresiones regulares son en realidad una herramienta bastante pobre para la validación del formato de dirección de correo electrónico. Un validador de formato verdaderamente completo implementado como una expresión regular es una monstruosidad de varios cientos de caracteres, mientras que la mayoría de los validadores "suficientemente buenos" más cortos que la mayoría de las personas tardan 5 minutos en crear rechazarán grandes categorías de direcciones válidas y entregables.
Dave Sherohman el
Te escucho amigo. Estaba hablando de lo "suficientemente bueno" y, si bien las grandes franjas pueden ser grandes en teoría, considere el porcentaje de cobertura que obtiene en una expresión tan corta. Yo también he visto la monstruosidad, pero ¿cuál es tu elegante alternativa?
Chris Morley el
2
He usado algo como \ w @ \ w +. \ W + para encontrar la dirección de correo electrónico rápidamente en un gran directorio de archivos donde la velocidad era importante y algunos falsos positivos o falsos negativos no lo eran. Pero la mejor manera de validar una dirección de correo electrónico parece ser enviarle un correo electrónico.
RossFabricant
Sí, la especificación de la dirección es un desastre desagradable stackoverflow.com/questions/611775/…
Nick Van Brunt
@Nick, @Dave: la validación de la dirección de correo no tiene por qué ser un desastre desagradable.
tchrist