Regular Expressions e C#
La classe base utilizzata per lavorare con le regular expression è Regex, il cui costruttore richiede la stringa di regular expression da utilizzare per l’elaborazione di stringhe.
Questa classe mette a disposizione una serie di metodi che permettono di:
- Ricercare un particolare pattern all’interno di una stringa
- Effettuare delle sosituzioni testuali
- Isolare alcuni gruppi di caratteri all’interno di una stringa
Sintassi delle Regular Expression
La stringa che definisce una regular expression utilizza una sintassi particolare che verrà descritti di seguito, basata su caratteri speciali a cui è associato uno specifico significato.
Nel caso in cui non siano specificati caratteri speciali, la stringa inserita come regular expression farà match con qualsiasi stringa contenente quel testo, in sostanza si avrà un comportamento del tutto analogo al metodo Contains() di string.
Es. “aaa” farà match con “aaabbb”, “bbaaacc”, “bbbbaaa” ecc.
Inizio e Fine
Per limitare il match a inizio o fine string è possibile utilizzare i caratteri speciali ^ per indicare l’inizio stringa e $ per indicare il fine stringa. Nel caso in cui la stringa sia composta da più righe e sia impostata l’opzione Multiline il match farà riferimento a qualsiasi riga, ovvero basterà una riga che soddisfi il criterio per avere il match della stringa nel suo complesso.
Es. “^aaa” fa match con “aaabbb”, “aaabbb(New Line)bbbccc”, “bbbaaa(New Line)aaabbb” (quest’ultima solo nel caso in cui sia specificato l’opzione multiline altrimenti non farà match)
Nel caso in cui si voglia il comportamento analogo di ^ e $ anche nel caso Multiline è possibile usare rispettivamente \A e \Z per inizio e fine di stringa, indipendentemente dalle righe
Es. “\Aaaa” fa match con “aaabbb”, “aaabbb(New Line)bbbccc”, mentre NON fa match “bbbaaa(New Line)aaabbb”
Nel caso in cui si vogliano considerare le singole parole (separate da spazi) è possibile utilizzare \b per indicare che il match è sui confini di una parola e \B per indicare che è all’interno della parola.
Es. “aa\b” fa match con “aabb cc”, “bbaa cc” ma non con “bbaabb” e “aa\B” fa match con “baab cc”, “cc caac”.
Molteplicità e Occorrenze
Nel caso in cui si vogliano ripetere alcuni caratteri 0 o più volte è possibile usare il carattere *,per una o più volte +, per un numero n specificato di volte {n} (con n numero di volte), n o più di n volte {n,}, da n a m volte {n,m}. Nel caso in cui si vogliano ripetere gruppi di caratteri è possibile utilizzare le parantesi tonde.
Es. “^a*$” farà match con “”, “a”, “aa” ecc. “^a+$” farà match con “a”, “aa” ecc ma non con “”. “^a{2}$” farà match con “aa”, “^(ab){2,3}$” farà match con “abab” e “ababab”.
Gruppi di Caratteri e Wildcards
Nel caso in cui si voglia far match con un carattere qualsiasi opzionale si può usare il carattere ?, mentre con un carattere qualsiasi obbligatorio . è possibile definire un gruppo di caratteri ammissibile tramite semplice elenco [abc] o [a|b|c] (farà match con il carattere a o b o c), un range [a-c] (farà match con i caratteri a o b o c)
Es. “^a?c$” farà match con “ac”,”aac”,”abc”, “a.c$” farà match con “abc”,”aac” ma non con “ac”, “^[ab]c$” farà match con “ac” e “bc”, “^[a-c]d$” farà match con “ad”, “bd”, “cd”
Di seguito altre wildcards utilizzabili
| \d | qualsiasi numero equivalente a [0-9] |
| \D | qualsiasi carattere NON numerico equivalente a [^0-9] |
| \s | qualsiasi carattere equivalente allo spazio |
| \S | qualsiasi carattere NON equivalente ad uno spazio |
| \w | qualsiasi carattere [a-zA-Z0-9] |
| \W | l’opposto del precedente [^a-zA-Z0-9] |
Gruppi
E’ possibile definire dei gruppi che è possibile ripetere e richiamare all’interno di una espressione regolare. La definizione di un gruppo avviene tramite caratteri ^(?<groupname>regex) in cui groupname è il nome del gruppo e regex è la regular expression che definisce quel gruppo. Per richiamare il gruppo è necessario usare \k<groupname>, in alternativa è possibile richiamare i gruppi con \n dove n è l’indice del gruppo in ordine di apparizione (da sinistra verso destra). I gruppi sono numerati a partire da 1 poichè il gruppo 0 è sempre il match completo dell’intera regular expression
Es."^(?<first>aa)bb\k<first>$” fa match con “aabbaa” così come "^(?<first>aa)(?<second>bb)\1$"”