Perché le espressioni regolari sono così controverse? [chiuso]


212

Quando si esplorano le espressioni regolari (altrimenti note come RegEx-es), ci sono molte persone che sembrano vedere le espressioni regolari come il Santo Graal. Qualcosa che sembra così complicato - deve essere solo la risposta a qualsiasi domanda. Tendono a pensare che ogni problema sia risolvibile usando espressioni regolari.

D'altra parte, ci sono anche molte persone che cercano di evitare le espressioni regolari a tutti i costi. Provano a trovare un modo per aggirare le espressioni regolari e accettano la codifica aggiuntiva solo per il gusto di farlo, anche se le espressioni regolari sarebbero una soluzione più compatta.

Perché le espressioni regolari sono considerate così controverse? Ci sono equivoci diffusi su come funzionano? O potrebbe essere una convinzione diffusa che le espressioni regolari sono generalmente lente?


9
se questa è una discussione, non dovrebbe essere chiusa? ma vedo una vera domanda lì dentro, quindi forse il tag di discussione non appartiene?
RCIX,

6
Non sto scherzando. Lo fai apparire e la gente inizia a impazzire qui.
Ryan Florence,

1
Bella osservazione e formulazione nella domanda!
imz - Ivan Zakharyaschev,


La domanda è basata sull'opinione, la regola dovrebbe applicarsi anche qui (o la domanda dovrebbe essere modificata per indirizzare una risposta precisa). Detto questo presumo che il regex controverse derivi dalla non precisione dei tutorial e dei manuali al riguardo. La maggior parte delle volte se non tutte le informazioni temporali sono miste e inoltre non ci vengono fornite tutte le caratteristiche. Aggiungendo a quell'uso linguistico imperfetto, si finisce per imparare qualcosa da notare lungo la strada che potrebbe significare qualcos'altro. E infine i caratteri regex speciali non si limitano a un significato che aggiunge ulteriore confusione.
Intika,

Risposte:


136

Non penso che le persone si oppongano alle espressioni regolari perché sono lente, ma piuttosto perché sono difficili da leggere e scrivere, oltre che difficili da ottenere. Mentre ci sono alcune situazioni in cui le espressioni regolari forniscono una soluzione efficace e compatta al problema, a volte vengono messe in discussione in situazioni in cui è meglio usare una sezione di codice di facile lettura e gestibile.


2
E sì, le regex possono essere estremamente lente rispetto all'utilizzo di semplici funzioni. E non solo lento, ma le prestazioni del motore regex possono essere totalmente imprevedibili di fronte a input arbitrari (forniti dall'utente).
Pacerier,

1
Se sai come funziona regex, non è affatto un problema.
Shiplu Mokaddim,

8
@pacerier, non sono schemi lenti , sono motori lenti . La maggior parte dei (moderni) motori di espressione regolare non sono adatti a schemi complessi (ad esempio molti |o .*), poiché utilizzano una macchina stack e un backtracking. Ecco perché devi mettere a punto con attenzione le tue espressioni regolari in Perl, Java, Python, Ruby ... I motori di espressioni regolari vecchio stile ( grepad esempio) per prima cosa compilano il modello in un DFA. Successivamente, la complessità del modello è in gran parte irrilevante. Ho appena usato Java e grep per lo stesso testo e lo stesso schema: 22 minuti contro 2 secondi. Ecco la scienza: swtch.com/~rsc/regexp/regexp1.html
hagello il

122

Rendere gestibili i regex

Un importante progresso verso la demistificazione degli schemi precedentemente definiti "espressioni regolari" è la /xbandiera regex di Perl - talvolta scritta (?x)quando incorporata - che consente spazi bianchi (interruzione di riga, rientro) e commenti. Ciò migliora notevolmente la leggibilità e quindi la manutenibilità. Lo spazio bianco consente il blocco cognitivo, in modo da poter vedere quali gruppi con cosa.

I modelli moderni ora supportano anche backreferences sia numerati che nominati. Ciò significa che non è più necessario contare i gruppi di acquisizione per capire che è necessario $4o \7. Questo aiuta quando si creano schemi che possono essere inclusi in ulteriori schemi.

Ecco un esempio di un gruppo di acquisizione relativamente numerato:

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

Ed ecco un esempio dell'approccio superiore delle catture nominate:

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

Regimi grammaticali

Soprattutto , queste acquisizioni nominate possono essere posizionate all'interno di un (?(DEFINE)...)blocco, in modo da poter separare la dichiarazione dall'esecuzione di singoli elementi nominati dei modelli. Questo li fa agire piuttosto come subroutine all'interno del modello.
Un buon esempio di questo tipo di "regex grammaticale" può essere trovato in questa risposta e in questa . Assomigliano molto più a una dichiarazione grammaticale.

Come quest'ultimo ti ricorda:

... assicurati di non scrivere mai schemi di rumore di linea. Non devi, e non dovresti. Non è possibile mantenere alcun linguaggio di programmazione che vieti spazi bianchi, commenti, subroutine o identificatori alfanumerici. Quindi usa tutte quelle cose nei tuoi schemi.

Questo non può essere enfatizzato eccessivamente. Naturalmente se non usi queste cose nei tuoi schemi, creerai spesso un incubo. Ma se si fa usarli, però, non è necessario.

Ecco un altro esempio di un modello grammaticale moderno, questo per analizzare RFC 5322: usare 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;

Non è straordinario - e splendido? Puoi prendere una grammatica in stile BNF e tradurla direttamente in codice senza perdere la sua struttura fondamentale!

Se i modelli grammaticali moderne ancora non sono abbastanza per voi, allora brillante di Damian Conway Regexp::Grammarsmodulo offre una sintassi più pulito, anche, con il debug superiore, anche. Ecco lo stesso codice per analizzare la rifusione di RFC 5322 in un modello da quel modulo:

#!/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
    }
}

C'è un sacco di roba buona nel perlre pagina man , ma questi notevoli miglioramenti nella funzionalità di progettazione regex fondamentali sono affatto limitati a Perl da solo. In effetti, la manpage PCrepattern può essere una lettura più semplice e copre lo stesso territorio.

I modelli moderni non hanno quasi nulla in comune con le cose primitive che ti hanno insegnato nella tua classe di automi finiti.


9
SÌ! SÌ! Infine, qualcuno mostra un ottimo esempio di quanto possano essere regex leggibili con il modificatore x. Non riesco a credere a quante poche persone sappiano che esiste, per non parlare del reale utilizzo.
Shabbyrobe,

1
@Shabbyrobe: non è solo /x. Sta usando le regex grammaticalmente, con (?&name)le subroutine regex interne, fa davvero brillare questo.
dal

+1 Impari sempre qualcosa di nuovo. Non sapevo che PCRE avesse una condizione "falsa" per definisce.
NikiC,

5
Python ha allo stesso modo una re.VERBOSEbandiera.
Lumaca meccanica

3
Solo Gunna va avanti e dice che sono ancora stupito dalle lunghezze che la gente farà per rendere utilizzabile regex.
Slater Victoroff

68

I regex sono un ottimo strumento, ma la gente pensa "Ehi, che grande strumento, lo userò per fare X!" dove X è qualcosa per cui uno strumento diverso è meglio (di solito un parser). È lo standard che utilizza un martello in cui è necessario un problema con un cacciavite.


4
Ricorda solo che la maggior parte dei parser - analizzatori ottici - usano ancora espressioni regolari per analizzare le loro cose :-)
Jasper Bekkers,

62
Dire che i parser usano espressioni regolari è come dire che i parser usano istruzioni di assegnazione. Non significa nulla finché non guardi per vedere come vengono utilizzati.
Chas. Owens,

24
Usare un RegEx quando un parser è migliore è fastidioso. L'uso di RegEx quando le funzioni di ricerca o sostituzione di stringhe standard della lingua funzioneranno (e in genere in tempi lineari) è semplicemente imperdonabile.
jmucchiello,

1
D'accordo, poiché un RegEx deve essere un tuttofare, il suo overhead di elaborazione è enorme. Solo perché l'utilizzo di un motore RegEx sembra facile non significa che sia una soluzione migliore rispetto a un parser iterativo (soglia dipendente dallo sviluppatore). Uno dei miei esempi preferiti di PHP split($pattern,$string)contro explode($delimiter,$string)- per fortuna il primo si sta deprezzando, ma un sacco di codice ha usato il primo quando avevano solo bisogno del potere del successivo. Complessivamente, i RegEx forniscono uno strumento semplice per fare alcune cose, ma a meno che tu non abbia bisogno della piena potenza delle espressioni regolari loro
Rudu

4
Gli analizzatori lessicali possono effettivamente usare regex. Sono anche noti come tokenizer, ma non sono analizzatori sintattici (o parser). Per leggere una stringa abbastanza complicata, un tokenizer dovrebbe essere usato per leggere la stringa come token (forse con regex, forse no, a seconda del tokenizer). Questi token dovrebbero quindi essere passati al parser, che li elaborerà con regole grammaticali, che sicuramente non sono regex.
Axel,

53

Quasi tutti quelli che conosco che usano regolarmente espressioni regolari (giochi di parole) provengono da un background Unix in cui usano strumenti che trattano le RE come costrutti di programmazione di prima classe, come grep, sed, awk e Perl. Dato che non c'è quasi nessun sovraccarico sintattico per usare un'espressione regolare, la loro produttività aumenta quando lo fanno.

Al contrario, i programmatori che usano linguaggi in cui le RE sono una libreria esterna tendono a non considerare quali espressioni regolari possono portare in tavola. Il "costo-tempo" del programmatore è così alto che a) le RE non sono mai apparse come parte del loro addestramento, oppure b) non "pensano" in termini di RE e preferiscono ricorrere a schemi più familiari.


11
Sì, non ho mai perdonato Python per aver reso verbale la sintassi della regex usando una libreria. Penso che sia purezza sopra sanità mentale.
Scorri il

7
Vengo da uno sfondo unix, ho usato carichi di sed, awk e perl, e ovviamente ho fatto un sacco di grepping, ma so che quando uso un regex, è un trucco di sola scrittura che odio mantenere. È buono per gli script di shell / one-timer, ma per il vero lavoro, per qualsiasi cosa che non sia solo un po 'di dati da salvare-ora, ora uso un tokenizer / lexer / parser corretto con una sintassi chiara. Il mio preferito fa tutto / nessuno, in modo pulito + può autoottimizzarsi. Ho imparato a mie spese, e per molti anni, che un po 'di autodisciplina all'inizio significa meno sforzi in seguito. Un regex è un momento sulla tastiera e una vita sul cipiglio.
AndrewC,

44

Le espressioni regolari consentono di scrivere una macchina a stati finiti (FSM) personalizzata in modo compatto, per elaborare una stringa di input. Esistono almeno due motivi per cui è difficile usare le espressioni regolari:

  • Lo sviluppo di software di vecchia scuola comporta molta pianificazione, modelli cartacei e attenta riflessione. Le espressioni regolari si adattano molto bene a questo modello, perché scrivere un'espressione efficace implica un sacco di fissarlo, visualizzando i percorsi di FSM.

    I moderni sviluppatori di software preferirebbero di gran lunga inserire il codice e utilizzare un debugger per eseguire l'esecuzione, per vedere se il codice è corretto. Le espressioni regolari non supportano molto bene questo stile di lavoro. Una "corsa" di un'espressione regolare è effettivamente un'operazione atomica. È difficile osservare l'esecuzione graduale in un debugger.

  • È troppo facile scrivere un'espressione regolare che accetti accidentalmente più input di quanto si pensi. Il valore di un'espressione regolare non corrisponde realmente a un input valido, ma non corrisponde a un input non valido . Le tecniche per eseguire "test negativi" per le espressioni regolari non sono molto avanzate, o almeno non ampiamente utilizzate.

    Questo fa sì che le espressioni regolari siano difficili da leggere. Basta guardare un'espressione regolare, ci vuole molta concentrazione per visualizzare tutti i possibili input che dovrebbero essere respinti, ma che vengono erroneamente accettati. Hai mai provato a eseguire il debug del codice delle espressioni regolari di qualcun altro ?

Se oggi c'è una resistenza all'uso delle espressioni regolari tra gli sviluppatori di software, penso che sia principalmente dovuto a questi due fattori.


4
Esistono strumenti eccellenti per eseguire il debug di regexps
Jasper Bekkers,

15
perl -Mre = debug -e "q [aabbcc] = ~ / ab * [cd] /"
Brad Gilbert,

15
Non credo di poter mai vedere l'acronimo "FSM" senza pensare al Flying Spaghetti Monster.
Shabbyrobe,

4
@Shabbyrobe: non intendo offendere. Se lo si desidera, è possibile utilizzare l'automa deterministico finito (DFA).
Bill Karwin,

37

Le persone tendono a pensare che le espressioni regolari siano difficili; ma è perché li stanno usando male. Scrittura di una riga complessa senza commenti, rientri o acquisizioni con nome. (Non stipare la tua complessa espressione SQL in una riga, senza commenti, rientri o alias, vero?). Quindi sì, per molte persone, non hanno senso.

Tuttavia, se il tuo lavoro ha qualcosa a che fare con l'analisi del testo (all'incirca qualsiasi applicazione web là fuori ...) e non conosci l'espressione regolare, fai schifo al tuo lavoro e stai sprecando il tuo tempo e quello del tuo datore di lavoro. Ci sono risorse eccellenti là fuori per insegnarti tutto ciò che devi sapere e altro ancora.


2
Bene ... la differenza è che più spazi hanno un significato in regex, dove in altre lingue non lo fanno ed è per questo che di solito sono una linea (che a volte si avvolge su più righe :)
Rado

14
@Rado: Perl, ad esempio, ha il xmodificatore per regex che fa ignorare gli spazi bianchi. Ciò ti consente di inserire il regex su alcune righe e aggiungere commenti.
Nathan Fellman,

9
Allo stesso modo Python ha re.Xaka re.VERBOSE.
Craig McQueen,

2
Allo stesso modo il xmodificatore in tcl. Credo che sia abbastanza standard poiché tcl, a differenza di altre lingue, non utilizza PCRE.
slebetman,

2
@AndrewC Questa è una delle più grossolane interpretazioni che questo post avrebbe potuto ottenere.
Jasper Bekkers,

28

Perché mancano dello strumento di apprendimento più popolare negli IDE comunemente accettati: non esiste un Wizard Regex. Nemmeno il completamento automatico. Devi codificare tutto da solo.


3
Quindi stai usando l'IDE sbagliato ... Anche il mio editor di testo fornisce suggerimenti regex.
CurtainDog

1
Da un lato, Expresso e The Regex Coach sono strumenti molto utili per costruire espressioni regolari.
Mun

22
In che modo completeresti automaticamente un'espressione regolare?
AmbroseChapel,

3
EditPad Pro ha l'evidenziazione della sintassi per le regex nella casella di ricerca, ma lo trovo più fastidioso che utile e lo tengo spento. Ma lo apprezzo facendomi sapere quando ho parentesi senza pari; le parentesi in particolare possono essere un orso di cui tenere traccia.
Alan Moore,

2
@AmbroseChapel - Sono in ritardo di un paio di anni a questa discussione. Ma ho creato un meccanismo di completamento automatico su regexhero.net/tester È iniziato dai costrutti comuni all'interno di parentesi tonde (), quadrate []o ricci {}. Funzionerà anche al di fuori della barra rovesciata.
Steve Wortham,


16

Non penso che siano così controversi.

Penso anche che tu abbia risposto in qualche modo alla tua domanda, perché fai notare quanto sarebbe sciocco usarli ovunque ( non tutto è un linguaggio normale 2 ) o evitare di usarli affatto. Tu, il programmatore, devi prendere una decisione intelligente su quando le espressioni regolari aiuteranno il codice o lo danneggeranno. Di fronte a tale decisione, due cose importanti da tenere a mente sono la manutenibilità (che implica la leggibilità) e l'estensibilità.

Per quelli che sono particolarmente avversi a loro, la mia ipotesi è che non abbiano mai imparato a usarli correttamente. Penso che la maggior parte delle persone che trascorrono solo poche ore con un tutorial decente li capiranno e diventeranno fluenti molto rapidamente. Ecco il mio suggerimento su dove iniziare:

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

Sebbene quella pagina parli di espressioni regolari nel contesto di Python, ho scoperto che le informazioni sono molto applicabili altrove. Ci sono alcune cose specifiche di Python, ma credo che siano chiaramente annotate e facili da ricordare.


2
La pagina sembra passare a docs.python.org/howto/regex
Dominic K

@DMan Grazie. Modificherò la mia risposta per riflettere.
codice alleato

11

Le espressioni regolari indicano agli operatori aritmetici i numeri e non li considererei controversi. Penso che anche un attivista di OO abbastanza militante come me (che tenderebbe a scegliere altri oggetti rispetto alle stringhe) sarebbe difficile da respingere.


7

Il problema è che le regex sono potenzialmente così potenti che puoi farci delle cose per cui dovresti usare qualcosa di diverso.

Un buon programmatore dovrebbe sapere dove usarli e dove no. L'esempio tipico è l'analisi di lingue non regolari (vedere Decidere se una lingua è regolare ).

Penso che non puoi sbagliare se inizialmente ti limiti a espressioni regolari reali (senza estensioni). Alcune estensioni possono rendere la tua vita un po 'più semplice, ma se trovi qualcosa di difficile da esprimere come una vera regex, questo potrebbe benissimo indicare che una regex non è lo strumento giusto.


5

Potresti anche chiederti perché i goto sono controversi.

Fondamentalmente, quando ottieni così tanto potere "ovvio", le persone sono inclini ad abusarne per situazioni per cui non sono l'opzione migliore. Il numero di persone che chiedono di analizzare CSV o XML o HTML in regex, per esempio, mi stupisce. È lo strumento sbagliato per il lavoro. Ma alcuni utenti insistono nell'utilizzare comunque le regex.

Personalmente, cerco di trovare quel mezzo felice - usa le regex per ciò a cui sono utili ed evitale quando sono meno che ottimali.

Nota che le regex possono ancora essere usate per analizzare CSV, XML, HTML, ecc. Ma di solito non in una singola regex.


Certo che puoi analizzare uno di questi formati in una sola regex, questo è il potere delle regex, piccola! Che tu lo voglia o no, è una questione completamente diversa.
Jasper,

4

Non penso che "controverso" sia la parola giusta.

Ma ho visto tonnellate di esempi in cui la gente dice "qual è l'espressione regolare di cui ho bisogno per fare una manipolazione del genere?" quali sono i problemi di XY.

In altre parole, sono partiti dal presupposto che una regex è ciò di cui hanno bisogno, ma starebbero meglio con uno split (), una traduzione come perl tr /// in cui i personaggi vengono sostituiti l'uno con l'altro, oppure solo un indice ().


4

Questo è un argomento interessante.
Molti appassionati di regexp sembrano confondere la concisione della formula con l'efficienza.
Inoltre, una regexp che richiede molto pensiero produce al suo autore un'enorme soddisfazione che la rende immediatamente legittima.

Ma ... le regexps sono così convenienti quando le prestazioni non sono un problema e devi affrontare rapidamente un output di testo, ad esempio in Perl. Inoltre, mentre le prestazioni sono un problema, è preferibile non provare a battere la libreria regexp utilizzando un algoritmo fatto in casa che potrebbe essere difettoso o meno efficiente.

Inoltre ci sono una serie di ragioni per le quali i regexps sono ingiustamente criticati, per esempio

  • il regexp non è efficiente, perché costruire quello in alto non è ovvio
  • alcuni programmatori "dimenticano" di compilare solo una volta una regexp da usare molte volte (come un modello statico in Java)
  • alcuni programmatori scelgono la strategia di prova ed errore - funziona ancora meno con regexps!

4

Quello che penso è Learning Regex e mantenere regex rende impopolare, la maggior parte degli sviluppatori è pigra o la maggior parte di loro si affida a librerie esterne per fare le analisi per loro ... si affidano a Google per la risposta e persino chiedono nei forum per il codice completo per il loro problema. Ma quando si tratta di implementare o modificare / mantenere una regex, semplicemente falliscono.

C'è un detto popolare "Gli amici non lasciano che gli amici utilizzino Regex per l'analisi dell'HTML"

Ma per quanto mi riguarda ho realizzato parser HTML completi usando Regex e trovo me stesso che regex è meglio nell'analisi delle stringhe HTML sia in termini di velocità che in termini di memoria (se hai un'idea che cosa vuoi ottenere :))


2
Penso che sia disonesto cancellare la maggior parte degli sviluppatori ... come pigro. Direi che la sintassi è molto criptica, non intuitiva e piena di gotcha, per i non iniziati, il che porta a un'elevata barriera all'ingresso. Per lo stesso motivo, Perl ha una "cattiva" reputazione per molti, ma è anche un linguaggio molto potente. È come cercare di leggere espressioni matematiche prima di conoscere i simboli. È scoraggiante e gli sviluppatori devono essere giudiziari con il loro tempo per sapere che trarranno benefici dall'apprendimento di quella sintassi.
Katastic Voyage,

Si sarà manca casi limite in HTML perché HTML non è un linguaggio regolare. Sei sicuro se la tua intenzione è quella di analizzare un sottoinsieme noto di HTML
Boyang,

2

Le espressioni regolari sono un grave mistero per molte persone, incluso me stesso. Funziona benissimo ma è come guardare un'equazione matematica. Sono felice di segnalare che qualcuno ha finalmente creato una posizione consolidata di varie funzioni di espressione regolare su http://regexlib.com/ . Ora se Microsoft creasse solo una classe di espressioni regolari che farebbe automaticamente gran parte delle cose comuni come eliminare le lettere o filtrare le date.


2
Ti manca il punto. L'idea dei regex è che investi un po 'di tempo nell'apprenderli e quando hai finito, non hai più bisogno di un magico corso di "lettura di un appuntamento". Invece, ci vuole pochissimo sforzo regex per loro. Inoltre, ci vorrà lo stesso sforzo per scriverne uno per un "aaaa / mm / gg" come per scriverne uno per "mm-gg-aaaa", o anche uno per "mm-aaaa / gg" (che ha vinto capita spesso, ma è un esempio di come puoi fare cose che una classe magica non può mai ").
Jasper,

1

Trovo le espressioni regolari inestimabili a volte. Quando ho bisogno di fare alcune ricerche "sfocate", e forse sostituisce. Quando i dati possono variare e avere una certa casualità. Tuttavia, quando ho bisogno di fare una semplice ricerca e sostituire, o controllare una stringa, non uso espressioni regolari. Anche se conosco molte persone che lo fanno, lo usano per tutto. Questa è la controversia.

Se vuoi mettere una virata nel muro, non usare un martello. Sì, funzionerà, ma quando avrai il martello, potrei mettere 20 chiodi nel muro.

Le espressioni regolari dovrebbero essere utilizzate per ciò per cui sono state progettate e niente di meno.


0

Mentre penso che le regex siano uno strumento essenziale, la cosa più fastidiosa è che ci sono implementazioni diverse. Lievi differenze di sintassi, modificatori e, soprattutto, "avidità" possono rendere le cose davvero caotiche, richiedendo tentativi ed errori e talvolta generando bug sconcertanti.


in che modo le implementazioni regex differiscono nel loro approccio alla corrispondenza massima, la cosa che penso tu stia chiamando "avidità"? Intendi la differenza tra semantica più a sinistra più lunga e più a sinistra più lunga ? Questa è l'unica differenza di cui sono a conoscenza; vale a dire, se l'avidità prevale sull'entusiasmo o viceversa .
tchrist

0

In alcuni casi penso che DEVI usarli. Ad esempio per costruire un lexer.

Secondo me, questo è un punto di vista delle persone che sanno scrivere regexp e delle persone che non lo fanno (o quasi). Personalmente, questa è una buona idea, ad esempio, per convalidare l'input di un modulo, sia in javascript per avvisare l'utente, sia in un linguaggio lato server.


0

Penso che sia una tecnica meno conosciuta tra i programmatori. Quindi, non vi è un'ampia accettazione per questo. E se hai un manager non tecnico per rivedere il tuo codice o rivedere il tuo lavoro, allora un'espressione regolare è pessima. Trascorrerai ore a scrivere una perfetta espressione regolare e otterrai pochi segni per il modulo pensando che abbia scritto così poche righe di codice. Inoltre, come detto altrove, leggere espressioni regolari è un compito molto difficile.


1
Leggere le espressioni regolari è un compito difficile solo quando il programmatore che le ha realizzate non è riuscito a utilizzare spazi bianchi, commenti, identificatori alfanumerici e forse anche subroutine incorporate tramite l'esecuzione ritardata. In breve, tutte le tecniche di ingegneria del software applicabili alla programmazione generale dovrebbero essere seguite anche in espressioni regolari. Se questi principi vengono ignorati, lo scrittore non produce codice professionale.
tchrist,

Penso che il tuo manager non sappia che "Il vero eroe della programmazione è quello che scrive codice negativo".
Rajeev,

Se il tuo manager ti chiederà di completare il lavoro con 3 righe di codice (comprese regexps), mentre elogi un collega doofus che lo ha fatto in 900 righe di Assembler ... Suggerisco di trovare un nuovo lavoro.
Phil Perry,

0

I sistemi di espressione regolare decenti come quelli usati in lex e yacc per la definizione del compilatore sono buoni, molto utili e puliti. In questi sistemi, i tipi di espressione sono definiti in termini di altri. Sono le espressioni orribili malformate, illeggibili, colle line-noise giganti, che si trovano comunemente nel codice perl e sed (ecc.) E sono "controverse" (spazzatura).


-4

Il miglior utilizzo valido e normale per regex è per la convalida del formato dell'indirizzo e-mail.

Questa è una buona applicazione.

Ho usato le espressioni regolari innumerevoli volte come una tantum in TextPad per massaggiare file flat, creare file CSV, creare istruzioni di inserimento SQL e quel genere di cose.

Le espressioni regolari ben scritte non dovrebbero essere troppo lente. Di solito le alternative, come tonnellate di chiamate da sostituire, sono opzioni molto più lente. Potrebbe anche farlo in un passaggio.

Molte situazioni richiedono espressioni esattamente regolari e nient'altro.

La sostituzione di caratteri speciali non stampabili con caratteri innocui è un altro buon uso.

Ovviamente posso immaginare che ci siano alcune basi di codice che abusano delle espressioni regolari a scapito della manutenibilità. Non l'ho mai visto da solo. In realtà sono stato evitato dai revisori del codice per non usare abbastanza espressioni regolari.


10
L'esperienza dimostra che le regex sono in realtà uno strumento piuttosto scarso per la convalida del formato dell'indirizzo e-mail. Un validatore di formato veramente completo implementato come regex è una mostruosità di più di cento caratteri, mentre la maggior parte dei validatori "abbastanza buoni" più corti che la maggior parte delle persone impiega 5 minuti per creare rifiuterà grandi categorie di indirizzi validi e consegnabili.
Dave Sherohman,

Ti sento amico. Stavo parlando del "abbastanza buono" e mentre le ampie strisce possono essere grandi in teoria, considera la percentuale di copertura che ottieni in un'espressione così breve. Anch'io ho visto la mostruosità, ma qual è la tua elegante alternativa?
Chris Morley,

2
Ho usato qualcosa come \ w @ \ w +. \ W + per trovare rapidamente l'indirizzo e-mail in un'enorme directory di file in cui la velocità era importante e alcuni falsi positivi o falsi negativi non erano importanti. Ma il modo migliore per convalidare un indirizzo e-mail sembra essere quello di inviare e-mail.
RossFabricant

Sì, e-mail la specifica dell'indirizzo è un brutto pasticcio stackoverflow.com/questions/611775/…
Nick Van Brunt

@Nick, @Dave: la convalida dell'indirizzo e-mail non deve necessariamente essere un disastro.
tchrist,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.