Michael Denny's Blog ;]


Tutto quello che non avresti mai voluto sapere sulle Regular Expression...e se sei qui ti tocca!
Archivio Posts
Anno 2017

Anno 2015

Anno 2014

Anno 2013

Anno 2012

Anno 2010

Anno 2008

Anno 2007

[RegEx] - Il punto prende (quasi) qualsiasi carattere

Eccomi di nuovo a scrivere sul mondo delle Regular Expression , mi sono ritagliato un po' di tempo da questo stupendo MICROSOFT MVP SUMMIT 2008 , per scrivere di un importantissimo carattere che sicuramente sarà utilizzato tantissimo.

- IL PUNTO

Prima di passare ad esaminare gli operatori "*?+" (come tutti già vorrebbero fare ), abbiamo bisogno di attendere ancora alcuni post, per avere tutti gli strumenti fondamentali per sfruttare al meglio quest'ultimi.

Nelle regular expression, il punto è uno dei più comuni metacaratteri utilizzati. Purtroppo è anche uno dei metacaratteri più abusato.

Il punto esegue il match di un singolo carattere, senza preoccuparsi di che carattere esso sia. L'unica eccezione è il carattere del ritorno a capo, ma che nei moderni motori regex è possibile attivarne il matching, abilitandone l'opportuno flag (Dot Matches newline (RegExBuddy) che per .NET è il flag RegexOptions.Singleline).

RegexBuddy


C#


VB.NET



- IL PUNTO VA UTILIZZATO CON MODERAZIONE!

Il punto è davvero un potente nelle regex, perchè ci permette di essere pigri, ma allo stesso tempo può creare grossi problemi, arrecandoci altrettanta confusione. Può succedere infatti che a volte ci si ritrovi con un matching completamente diverso da quello aspettato.

Vi farò vedere questo con un semplice esempio. Mettiamo per esempio, che volessimo matchare una data, ma vogliamo lasciare all'utente la libertà di scegliere il separatore. Una prima e veloce soluzione sarebbe \d\d.\d\d.\d\d\d\d. Sembrerebbe giusta ad una prima occhiata, prende correttamente date come 15/04/2008. Il problema lo si ha però con 1520472008, che anche esso verrebbe preso come una data valida, questo perchè il primo punto prende il carattere '2' e il secondo il '7', perchè come si è detto prima, il punto prende qualsiasi carattere, di conseguenza ovviamente la regex del nostro esempio, non è logicamente corretta.



Una soluzione migliore potrebbe essere questa: \d\d[- /.]\d\d[- /.]\d\d\d\d. Questa regex prende come separatore valido la barra '/', lo spazio ' ', il meno '-' e il punto '.'. Da ricordare che il punto non diventa un metacarattere all'interno del set di caratteri, quindi non abbiamo bisogno di farci l'escape con la barra '\'.



La suddetta regex è ben lontana dalla perfezione, perchè prende come valide anche date come 99/99/9999. Uno step successivo potrebbe essere questo [0-3]\d[- /.][0-1]\d[- /.]\d\d\d\d, ma comunque continuerebbe ad accettare date come 39/19/99. La vostra regex dovrà essere costruita quanto più perfetta, in base alle vostre esigenze. Se ad esempio si sta validando un input utente, la regex dovrà essere perfetta, mentre se si sta caricando un file dove la data è pressoche sempre nella stessa sintassi, allora sarà sufficiente applicare una regex che controlli solo la sintassi.

Una regular per validare una data in maniera piuttosto precisa, potrebbe essere la seguente: (0[1-9]|[12][0-9]|3[01])[- /.](0[1-9]|1[012])[- /.](19|20)[0-9]{2} dove l'anno può variare da 1900 a 2099, come si può notare dall'esempio sottostante:




- UTILIZZARE SET DI CARATTERI NEGATI INVECE CHE IL PUNTO

Supponete di volere prendere con la vostra regex una stringa con doppi apici agli estremi. Ad una prima occhiata potrebbe sembrare facile, con una semplice regex del tipo ".*" il nostro scopo sembra essere raggiunto bene. Il punto prende ogni carattere, e l'asterisco permette al punto di ripetersi tutte le volte necessarie, anche zero volte. Se proverete a testare la regex su Mettere una "stringa" in mezzo a doppi apici, restituirà correttamente "stringa". Ora proviamo a testare la stessa regex su Con due stringhe come queste "stringa uno" e "stringa due" si riscontrano problemi. Qui la regex non fa più il suo dovere, o meglio, continua a farlo benissimo, ma il risultato che ci aspettavamo non è quello restituito cioè: "stringa uno" e "stringa due". Il perchè ha tutto questo lo si trova nell'asterisco che è ingordo.



Come per la regex della data, utilizzeremo anche qui i set di caratteri, per correggere la nostra regex, però invece che utilizzare i normali set di caratteri, utilizzeremo quelli negati. Ragionando in logica inversa, la regex dovrà escludere tutti i doppi apici ed eventuali ritorni a capo, e quindi la corretta regex risulta la seguente: "[^"\r\n]*"



L'uso dei set di caratteri negati, verrà spiegato più dettagliatamente quando presenterò gli operatori *+, ma è stato abbastanza importante da doverlo menzionare subito anche qui.


Stay Tuned!
Categoria: Regular Expression
martedì, 15 apr 2008 Ore. 23.20
Calendario
aprile 2024
lmmgvsd
25262728293031
1234567
891011121314
15161718192021
22232425262728
293012345





Statistiche
  • Views Home Page: 82.396
  • Views Posts: 80.154
  • Views Gallerie: 0
  • n° Posts: 31
  • n° Commenti: 18
Copyright © 2002-2007 - Blogs 2.0
dotNetHell.it | Home Page Blogs
ASP.NET 2.0 Windows 2003