Commentare espressioni regolari


11

Esistono pratiche comuni per commentare le espressioni regolari: commenti incorporati che fanno riferimento a parti diverse di RegEx o commenti generali per tutte le espressioni?


2
Ci sono ma devi essere più specifico. Ad esempio Bash supporta i commenti incorporati e Python offre espressioni regolari dettagliate.
sakisk,

6
La mia regola empirica per le espressioni regolari è: se devi commentare l'espressione regolare, è troppo complicata.
zzzzBov,

1
E includi sempre questo link: regexcrossword.com
Kieveli,

Non sono necessariamente d'accordo sul fatto che se devi commentarlo, è troppo complicato. Un regex complicato può ancora farti risparmiare tonnellate di codice imperativo strabiliante. Utilizzare un buon nome di variabile descrittivo per assegnare la regex. Se non è ancora abbastanza chiaro, usa un breve commento per comunicare l' intento originale dietro l'espressione regolare.
Craig,

Risposte:


10

Dal mio punto di vista, una buona pratica è quella di affermare in modo conciso nei commenti quale sia l'idea generale dell'espressione regolare. Questo evita agli altri sviluppatori (o talvolta a te stesso) la seccatura di incollare la regex in un parser come RegExr , solo per capire cosa fa.


2
RegExr accadrà comunque, a meno che lo sviluppatore non sia un esperto di regex. Ma sono d'accordo nel fornire una descrizione generale; questo è quello che faccio con le mie regex.
Robert Harvey,

3
+1: Qualsiasi cosa più dettagliata finirà per essere un corso intensivo in regex come commento.
Matt,

Questa risposta e i commenti di @zzzzBov hanno un senso.
m0nhawk,

1
Non solo salva la seccatura dell'esame noioso dell'espressione regolare per capirla, ma rende chiara l'intenzione del programmatore originale, soprattutto data la chiara possibilità che il programmatore originale abbia ottenuto l'espressione regolare stessa nel corso dei primi tempi. Detto questo, in molti casi l'assegnazione della regex a un buon nome di variabile può fare molto per fornire un'adeguata documentazione di intenti.
Craig,

9

Questa è in qualche modo una risposta specifica per la lingua, ma nessuna domanda è indicata nella domanda.

Il libro "Dive Into Python" suggerisce l'implementazione di commenti usando le espressioni regolari verbose :

Python ti consente di farlo con qualcosa chiamato espressioni regolari verbose. Un'espressione regolare dettagliata è diversa da un'espressione regolare compatta in due modi:

  • Lo spazio bianco viene ignorato. Spazi, tabulazioni e ritorni a capo non corrispondono a spazi, tabulazioni e ritorni a capo. Non sono affatto abbinati. (Se si desidera abbinare uno spazio in un'espressione regolare dettagliata, è necessario evitarlo mettendo una barra rovesciata di fronte ad esso.)
  • I commenti vengono ignorati. Un commento in un'espressione regolare dettagliata è proprio come un commento nel codice Python: inizia con un #carattere e arriva fino alla fine della riga. In questo caso è un commento all'interno di una stringa a più righe anziché all'interno del codice sorgente, ma funziona allo stesso modo.

Esempio:

>>> pattern = """
^                   # beginning of string
M{0,4}              # thousands - 0 to 4 M's
(CM|CD|D?C{0,3})    # hundreds - 900 (CM), 400 (CD), 0-300 (0 to 3 C's),
                    #            or 500-800 (D, followed by 0 to 3 C's)
(XC|XL|L?X{0,3})    # tens - 90 (XC), 40 (XL), 0-30 (0 to 3 X's),
                    #        or 50-80 (L, followed by 0 to 3 X's)
(IX|IV|V?I{0,3})    # ones - 9 (IX), 4 (IV), 0-3 (0 to 3 I's),
                    #        or 5-8 (V, followed by 0 to 3 I's)
$                   # end of string
"""
>>> re.search(pattern, 'M', re.VERBOSE)                1

Fonte e ulteriori dettagli qui

Questo metodo ha un leggero svantaggio che il chiamante deve sapere che il modello è scritto in un formato dettagliato e chiamarlo di conseguenza.


2
Invece di memorizzare il modello in una variabile, è possibile utilizzare re.compilenel punto in cui si definisce il modello e memorizzare solo l'oggetto risultante. In questo modo, i flag di compilazione dei pattern (incluso re.VERBOSE) non devono essere separati dal pattern stesso.
John Bartholomew,

Risposta davvero utile, grazie! Ma come posso abbinare a #se sto usando il flag dettagliato? A proposito: i collegamenti di origine sembrano essere inattivi.
winklerrr,

Va bene, quindi #può essere abbinato letteralmente all'interno di una classe di caratteri: [#](fonte: docs.python.org/3/library/re.html#re.X )
winklerrr

8

Tipicamente, scriverò una regex e non spiegherò i singoli pezzi della regex, ma piuttosto qual è il suo scopo. Questo è ciò che e perché. È un po 'come chiedere "Come dovrebbero essere i miei commenti?" a cui si direbbe " Non scrivere cosa sta facendo il codice, scrivere perché il codice sta facendo quello che fa "

// Strip the leading "?" and remove the query parameters "offset=<integer>" & "count=<integer> so we have a pattern of the request"          
var search = location.search.substring(1).replace(/offset=[0-9]+?&/g, "").replace(/count=[0-9]+?&/g, "");

A meno che tu non stia cercando di insegnare a qualcuno sulle regex tramite commenti in codice, non penso che spieghi cosa farà ogni singolo pezzo. Quando lavori con altri programmatori, puoi tranquillamente supporre che uno saprebbe qualcosa come espressioni regolari globali.


3
rimarrai sorpreso ...
Matt,

6

Immagino che dipenda davvero da come stai mettendo insieme la regex. In generale, penso che sarebbe una cattiva idea inserire commenti all'interno della stringa regex stessa (non è possibile nella maggior parte degli scenari, per quanto ne so). Se hai davvero bisogno di commentare parti specifiche di un'espressione regolare (stai cercando di insegnare a qualcuno?), Allora spezza ogni blocco in stringhe separate sulle loro stesse linee e commenta ogni riga usando il normale processo di commento per il tuo linguaggio di programmazione. Altrimenti, la risposta di pleinolijf è piuttosto buona.

esempio:

string myregex = "\s" // Match any whitespace once
+ "\n"  // Match one newline character
+ "[a-zA-Z]";  // Match any letter

4

Di solito definisco una costante di stringa il cui nome descrive lo scopo generale dell'espressione regolare.

Per esempio:

const string FloatingPointNumberPattern = @"[-+]?[0-9]*\.?[0-9]+";

Puoi aggiungere un commento sopra questa costante per dargli una descrizione, ma di solito il nome della costante stessa dovrebbe essere sufficiente.


1
Una cosa in più che mi piace di questa risposta è che se viene utilizzata in più di un punto, anche l'intento deve essere portato in giro, senza dimenticare di commentarlo.
J Trana,

3

In alcuni scenari, gli sviluppatori potrebbero utilizzare espressioni regolari per far corrispondere il testo al di fuori del loro dominio tipico. Gli sviluppatori originali potrebbero aver attraversato molte iterazioni catturando vari casi limite che potrebbero essere stati scoperti solo attraverso quel processo iterativo. Pertanto, gli sviluppatori successivi potrebbero non essere a conoscenza di molti casi limite che gli sviluppatori originali hanno trattato, anche se sono a conoscenza del caso generale.

In casi come questi, può essere utile documentare esempi delle variazioni. La posizione di questa documentazione può variare in base all'importo (ad esempio, non necessariamente nel codice).

Un modo per affrontarlo è quello di supporre che i futuri sviluppatori avranno solo conoscenze di base, come il funzionamento delle espressioni regolari, ma non tutte le conoscenze che entrambi (1) avevi prima dello sviluppo delle espressioni regolari che non sarebbero necessariamente note al futuri sviluppatori o (2) conoscenze acquisite durante lo sviluppo (ad esempio casi limite scoperti).

Ad esempio, se durante lo sviluppo dici qualcosa del tipo "Oh, non sapevo che X potesse prendere questa forma", allora vale la pena documentarlo (e forse la parte della regex che gestisce quella variazione).


2

I commenti dovrebbero aggiungere informazioni utili che non sono ovvie dal codice.

  1. Semplifica la comprensione di cosa dovrebbe fare l'espressione a livello di requisiti, nel codice stesso o in un commento. Qual è l'intento dietro l'espressione, è convalidare gli indirizzi e-mail o selezionare i numeri di telefono canadesi.
  2. Rendi facile capire cosa sta realmente facendo l'espressione, ovvero a cosa valuta l'espressione. Per prima cosa prova a chiarire dividendo l'espressione, se prima controlli tutti i trattini, quindi rimuovi tutti i numeri e poi fai che un'espressione in due parti con variabili che contengano i valori intermedi, renderà molto più facile la lettura e il lettore sarà in grado di scorrere la tua logica un passo alla volta. (C'è una famosa risposta a una domanda su SE in cui qualcuno sta cercando di decifrare qualche vecchio codice che comporta la manipolazione dei bit '>>' e scoprire se alcuni flag sono impostati in cui la risposta indica non solo ciò che il codice fa davvero, ma come l'autore della domanda dovrebbe riguardare la decostruzione di questo tipo di codice in futuro, che è esattamente quello che sto cercando di descrivere, ma posso "

Esistono poche applicazioni che richiedono ogni ultimo ciclo, se si esegue il pattern matching di enormi set di dati, forse c'è un modo migliore, forse no, ma per la maggior parte dei tempi il tempo di esecuzione extra non è un grosso problema.

E ricorda che la prossima persona che incontrerà il tuo codice e risolverà un bug potresti essere tu tra sei mesi e non avrai modo di ricordare cosa avrebbe dovuto fare.


1

Estrarre il RegEx in una classe separata in un con un nome significativo. Quindi documenterei il codice con test automatici.

Questo assicurerà

  • Che il codice funzioni davvero, anche per casi angolari
  • Assicura che un rapido "bugfix" non rovini molti casi angolari
  • Può documentare ottimizzazioni in cui il backtracking è disabilitato

Naturalmente, la tua classe può ospitare diversi regex.

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.