Hey, Scripting Guy!Impossibile confondere le espressioni regolari

Microsoft Scripting Guys

Scarica il codice per questo articolo: HeyScriptingGuy2008_01.exe (150KB)

Tutti fanno errori.Pensavi che il team degli Scripting Guys fosse stato creato apposta?Tuttavia, se esiste un aspetto positivo degli errori, questo è... che cos'è?Pensavi che avremmo detto che l'aspetto positivo è che si può imparare dagli errori commessi?Cielo, no:l'unica cosa che si impara da un errore è che sarebbe stato meglio non averlo mai fatto.

Nota:ci dispiace, ma non ci saranno battute su Microsoft Bob, non oggi.Abbiamo commesso l'errore di prenderci gioco di Microsoft Bob una volta e, in quel caso, abbiamo imparato dal nostro errore.Se si tratta di Microsoft Bob, le nostre labbra sono serrate.

A essere onesti, non riusciamo davvero a trovare niente di buono negli errori, ecco perché abbiamo dedicato le nostre vite a ridurre gli sbagli che commettiamo(diciamolo pure, l'unico modo per ridurre gli errori sarebbe diminuire il numero di cose che facciamo... ma questa è un'altra storia).

Ora, va benissimo tentare di ridurre i nostri errori, tuttavia non risolve molto se le persone con cui lavoriamo continuano a farne(no, l'abbiamo già detto:nessuna battuta su Microsoft Bob!).Se hai mai scritto un front-end su, mettiamo, un programma di database o Active Directory® (e sappiamo che la gran parte dei nostri lettori l'hanno fatto), allora sai perfettamente di cosa parliamo:il programma di immissione dei dati front-end è efficace solo nella misura in cui lo sono coloro che immettono questi dati.

Immagina di voler inserire in questo modo i nomi propri:Ken, con la prima lettera in maiuscolo e le altre in minuscolo.Cosa succede se un utente immette il nome così:KEN?Immagina di voler inserire in questo modo le date:01/23/2007. Cosa succede se un utente immette una data così:23 gennaio 2007?Immagina... beh, il concetto dovrebbe essere chiaro.Come abbiamo detto, il programma di immissione dei dati front-end è efficace solo nella misura in cui lo sono coloro che immettono questi dati.E, piaccia o no, le persone addette all'immissione dei dati commettono degli errori.A meno che, ovviamente, non si prendano delle misure per assicurarsi che non si verifichino.

Verifica che i dati siano validi

Che i Giochi abbiano fine

Ti sei mai chiesto quale evento gli Scripting Guys attendono con trepidazione tutto l'anno?Se hai visitato lo Script Center nel mese di febbraio negli scorsi due anni, potresti pensare che parliamo dei Giochi invernali di scripting.Beh, avresti torto.Gli Scripting Guys aspettano la fine dei Giochi invernali di scripting quando, dopo due settimane di divertimento ininterrotto, possono crogiolarsi dopo l'ennesima vittoria e dormire per tutto il mese successivo.

Quindi, in attesa del nostro evento annuale preferito, la fine dei Giochi di scripting, è ora di iniziare i Giochi invernali di scripting 2008!Unisciti a noi dal 15 febbraio al 3 marzo 2008 allo Script Center per partecipare a più di due settimane di divertimento e alla competizione di scripting più emozionante in circolazione.

I Giochi di scripting sono un'ottima occasione per verificare, e migliorare, le tue capacità di scripting.Inoltre, visto che quest'anno vogliamo dormire qualche altro giorno dopo la fine dei Giochi, stiamo rendendo la competizione del 2008 ancora più grande e ricca dell'anno scorso.Anche quest'anno, sono previste due suddivisioni:Principianti e Avanzati.Sei un novellino dello scripting, un vecchio (o giovane) professionista o qualcosa nel mezzo? Questa è comunque la competizione perfetta per te.

Quali sono le novità di quest'anno?Stiamo aggiungendo un nuovo linguaggio di script.Puoi partecipare alla competizione per VBScript, Windows PowerShell o, ecco la novità, Perl(sappiamo che Perl non è un linguaggio nuovo, ma è una novità per i Giochi).Probabilmente questo aumenterà il divertimento, ma, visto che abbiamo dovuto inserire questa intestazione laterale mesi fa, non abbiamo idea di come sarà.Dovrai venire allo Script Center per scoprire cosa ci siamo inventati.

Se te lo stai chiedendo, sì, ci saranno anche i premi.Quali?Hey, non vogliamo rovinare la sorpresa! Vieni allo Script Center e scoprilo. microsoft.com/technet/scriptcenter/funzone/games/default.mspx.

Molti lettori probabilmente stanno già eseguendo qualche tipo rudimentale di convalida dell'immissione dei dati.E, sotto molti aspetti, questo tipo elementare di convalida dell'immissione dei dati è assolutamente adeguato.Devi assicurarti che il valore della stringa strName contenga un numero pari o inferiore a 20 caratteri?Puoi utilizzare questo piccolo blocco di codice:

If Len(strName) > 20 Then
    Wscript.Echo "Invalid name; a " & _
    "name must have 20 or fewer characters."
End If

Supponi, però, che strName sia un nuovo numero di parte. I numeri di parte devono rispettare un modello specifico:quattro cifre seguite da due lettere maiuscole (ad esempio, 1234AB).Utilizzando semplicemente VBScript, si può verificare se strName rispetta il modello necessario per i numeri di parte?Sì, certo.Ma, fidati, è meglio non usarlo.Piuttosto, puoi utilizzare un'espressione regolare.

Verifica che in un valore vengano visualizzati solo numeri

Le espressioni regolari risalgono agli anni '50, quando furono descritte per la prima volta come una forma di notazione matematica.Negli anni Sessanta, questo modello matematico fu incorporato nell'editor di testo QED come soluzione per la ricerca di modelli di caratteri in un file di testo.In seguito... che c'è?Oh.Sembra che la storia delle espressioni regolari non sia tanto appassionante per i lettori come lo è per noi. Va bene.In questo caso, ci limiteremo a mostrare di cosa stiamo parlando.

Vuoi verificare che una variabile (in questo caso, la variabile strSearchString) contenga solo numeri?Nella Figura 1 viene mostrata una delle soluzioni per eseguire la verifica.

Figure 1 Solo numeri, per favore

Set objRegEx = _
  CreateObject("VBScript.RegExp")

objRegEx.Global = True   
objRegEx.Pattern = "\D"

strSearchString = "353627"

Set colMatches = _
  objRegEx.Execute(strSearchString)  

If colMatches.Count > 0 Then
    Wscript.Echo "Invalid: a " & _
      "non-numeric character was found."
Else
    Wscript.Echo "This is a valid entry."
End If

Come si può vedere, lo script inizia dalla creazione di un'istanza dell'oggetto VBScript.RegExp, l'oggetto che... sì, hai ragione... l'oggetto che consente di utilizzare le espressioni regolari nello script(volevamo essere noi a spiegarlo).Quindi, assegniamo i valori a due proprietà principali dell'oggetto delle espressioni regolari:Global e Pattern.

La proprietà Global determina se lo script debba corrispondere a tutte le occorrenze di un modello o debba solo individuare la prima di tali occorrenze e quindi arrestarsi.In generale, si consiglia di impostare questo valore su True per consentire la ricerca di tutte le occorrenze di un modello(l'impostazione predefinita è False).Spesso, potrebbe essere necessario trovare tutte le occorrenze di un modello.Anche in caso contrario, l'unico vantaggio legato alla ricerca della sola prima occorrenza di un modello consiste nella maggiore velocità di esecuzione dello script poiché si arresta prima di completare l'intera ricerca.In teoria, sembra un vantaggio significativo.In pratica, tuttavia, la ricerca viene completata così rapidamente che non si è in grado di rilevare la differenza.

Ecco l'aspetto positivo:la proprietà Pattern indica dove si specificano i caratteri (e il modello di carattere) desiderati. Nello script di esempio, la ricerca viene eseguita per qualsiasi carattere che non sia una cifra compresa tra 0 a 9. Se si individua questo carattere (una lettera, un segno di punteggiatura o altro), il valore assegnato a strSearchString non è valido.Con le espressioni regolari, la sintassi \D viene utilizzata per la ricerca di caratteri non numerici; quindi, viene assegnato il valore \D alla proprietà Pattern.

Nota:come sappiamo che \D corrisponde a caratteri non numerici?Beh, è una lunga storia.Tanti anni fa... oh, ok.Lo abbiamo trovato nei riferimenti relativi al linguaggio VBScript in MSDN® all'indirizzo msdn2.microsoft.com/1400241x.

Dopo aver assegnato i valori alle proprietà Global e Pattern, il passaggio successivo consiste nell'assegnazione di un valore alla variabile strSearchString:

strSearchString = "353627"

Come verifichiamo l'assenza di caratteri non numerici in questa stringa?La risposta è semplice.Basta chiamare il metodo Execute che esegue una ricerca della variabile per qualsiasi carattere non numerico:

Set colMatches = _
objRegEx.Execute(strSearchString)

Quando si chiama il metodo Execute, tutte le corrispondenze trovate, ossia tutte le istanze di Pattern, vengono archiviate automaticamente nella raccolta Matches(nello script di esempio, il nome della raccolta è colMatches).Per sapere se la variabile contiene caratteri non numerici (e noi lo sappiamo), è sufficiente controllare il valore della proprietà Count della raccolta che segnala quanti elementi sono nella raccolta:

If colMatches.Count > 0 Then
    Wscript.Echo "Invalid: a " & _
      "non-numeric character was found."
Else
    Wscript.Echo "This is a valid entry."
End If

Se il valore di Count è maggiore di 0 significache è stato rilevato un carattere non numerico nel valore della variabile.Se tutti i caratteri nel valore fossero cifre, la raccolta sarebbe vuota e avrebbe un valore Count pari a 0.Nello script di esempio, viene illustrato il rilevamento di caratteri non numerici.In un front-end reale di script o database, viene probabilmente visualizzato un messaggio analogo e l'operazione viene riportata indietro per consentire all'utente di riprovare.Ma c'è tempo per preoccuparsi di questo: come Scripting Guys, abbiamo molte altre cose di cui preoccuparci.

Ad esempio?Ad esempio, il pensiero che un giorno le persone di TechNet Magazine possano realmente iniziare a leggere gli articoli che gli mandiamo ogni mese.Vorremmo piuttosto che non imparassero dai loro errori.

Ah, buona domanda:non è possibile utilizzare semplicemente la funzione IsNumeric per determinare se strSearchString contiene un numero?Certo, sempre che il valore strSearchString possa corrispondere a qualsiasi numero.Ma che succede se il valore strSearchString deve essere un numero intero positivo?Questo potrebbe essere un problema: IsNumeric identifica entrambi i valori come numeri validi:

-45
672.69

Perché questi valori sono identificati come numeri validi?Perché sono effettivamente numeri validi, anche se non interi positivi.L'espressione regolare contrassegna invece questi numeri come voci non valide poiché è in grado di distinguere il segno meno (–) e il punto (.) dei caratteri non numerici.Se stai leggendo questo articolo e ti chiedi perché, ecco, questa è una buona ragione.

Che hai detto?Non è abbastanza interessante?Wow, lettori esigenti questo mese!OK, passiamo a qualche altro tipo di convalida dell'immissione dei dati ottenuta utilizzando le espressioni regolari.

Verifica che in un valore non vengano visualizzati numeri

Ti abbiamo appena spiegato come verificare che in un valore vengano visualizzati solo numeri.In che modo si potrebbe fare il contrario, ossia verificare che non vengano visualizzati numeri nel valore?Bene, ecco qui un modello di ricerca che è possibile utilizzare:

objRegEx.Pattern = "[0-9]"

Che succede?Nel mondo folle e selvaggio delle espressioni regolari, i caratteri parentesi ([ e ]) consentono di specificare un insieme di caratteri oppure, come in questo caso, un intervallo di caratteri.Che cosa significa il valore Pattern [0-9]?Significa che la ricerca viene eseguita su qualsiasi carattere nell'intervallo da 0 a 9, in altre parole su qualsiasi valore numerico.Per ottenere solo numeri pari (ossia, per verificare che il valore non includa numeri con 1, 3, 5, 7 o 9), si utilizza questo modello:

objRegEx.Pattern = "[13579]"

Tieni presente che, poiché non abbiamo utilizzato il trattino, non stiamo cercando un intervallo di caratteri.In realtà, cerchiamo esattamente i caratteri 1, 3, 5, 7 e 9.

Naturalmente, il modello [0-9] cerca solo i numeri; non individua segni di punteggiatura o altri caratteri diversi sia dalle lettere che dai numeri.Pensi sia possibile creare un modello per cercare qualsiasi carattere diverso dalle lettere?Ovviamente sì.Con le espressioni regolari, puoi fare praticamente tutto:

objRegEx.Pattern = "[^A-Z][^a-z]"

In questo caso, stiamo integrando due criteri nel modello:la ricerca viene eseguita per [^A-Z] e [^a-z].Come probabilmente immagini, A-Z indica l'intervallo di caratteri dalla A maiuscola alla Z maiuscola. Che cosa significa il carattere ^?Se all'interno delle parentesi quadre, il segno ^ indica la ricerca per qualsiasi carattere non compreso nell'intervallo di caratteri specificato.Quindi [^A-Z] indica di cercare tutti i caratteri non maiuscoli.Allo stesso tempo, [^a-z] indica di cercare tutti i caratteri non minuscoli.Il risultato finale:questo modello indica una ricerca di qualsiasi elemento che non sia una lettera maiuscola o minuscola.Ciò include numeri, segni di punteggiatura e qualsiasi altro tipo di strano carattere che si trova sulla tastiera.

In alternativa, si può impostare la proprietà IgnoreCase su True:

objRegEx.IgnoreCase = True

In questo modo, la ricerca ignora le maiuscole e le minuscole.Inoltre, potremmo utilizzare questo modello che, combinato con la proprietà IgnoreCase, consente di cercare qualsiasi elemento che non sia una lettera in maiuscolo o minuscolo:

objRegEx.Pattern = "[^A-Z]"

Verifica che un numero di parte sia valido

E adesso, un po' di fantasia.E, credici, puoi davvero scatenarti con le espressioni regolari; per qualche esempio, dai un'occhiata al sito Web regexlib.com.Prima, in questo articolo, abbiamo scritto:Supponi che strName sia un nuovo numero di parte. I numeri di parte devono rispettare un modello specifico:quattro cifre seguite da due lettere maiuscole (ad esempio, 1234AB).In che modo puoi verificare che la variabile rispetti questo modello?Un modello come questo, ovviamente:

objRegEx.Pattern = "^\d{4}[A-Z]{2}"

Che cosa indica questo modello?Che coincidenza:stavamo appunto per spiegarlo.In questo caso, la ricerca viene eseguita su tre criteri:

^\d{4} 

Con \d si indica la ricerca di cifre (un carattere compreso nell'intervallo tra 0 a 9).Che cosa indica {4}?Indica che la ricerca deve produrre una corrispondenza esatta di quattro caratteri (ossia, esattamente quattro cifre).Quindi, stiamo cercando quattro cifre consecutive.

Infine, che significa il carattere ^?Fuori dalle parentesi quadre, il segno ^ indica che il valore deve iniziare con il modello successivo; ciò significa che AA1234AB non sarà contrassegnato come corrispondenza.Perché?Perché il valore inizia con AA, non con quattro cifre consecutive.Volendo, è possibile utilizzare il carattere $ per indicare che la corrispondenza deve trovarsi alla fine della stringa.Ma non vogliamo(almeno, non in questo esempio).

[A-Z]{2} 

Sai già cosa indica il componente [A-Z], ossia qualsiasi lettera maiuscola.E {2}?Esatto:le quattro cifre devono essere seguite esattamente da due caratteri maiuscoli.

Facile, eh?A proposito, in questo caso se Count è 0, il valore non è valido.Perché?Dunque, in questo caso non cerchiamo un singolo carattere che invalidi la stringa, ma piuttosto una corrispondenza esatta al modello.Se non la otteniamo, significa che il valore non è validoe che la proprietà Count della raccolta sarà 0.

Nota:Due altre costruzioni utili sono:{3,} e {3,7}.{3,} segnala la presenza di almeno tre caratteri (o espressioni) consecutivi; tuttavia, mentre il numero minimo di caratteri è fissato a tre, non esiste un limite massimo.Questo \d{3,} corrisponde a 123, a 1234 e anche a 123456789. {3,7} richiede, invece, un numero di caratteri (o espressioni) consecutivi compreso tra 3 e 7. Quindi, 123456 è una corrispondenza, ma 123456789 (che contiene più di sette cifre) non lo è.

Ecco un altro modello utile.Immagina che il numero di parte inizi con quattro cifre seguite dalle lettere US, seguite da due caratteri finali (lettere, numeri o altro).Esiste una sola corrispondenza:

objRegEx.Pattern = "^\d{4}US.."

Come si può vedere, questo modello inizia con quattro cifre (\d), che devono essere seguite dai caratteri US (esclusivamente da queste due lettere; qualsiasi altro carattere non verrebbe considerato una corrispondenza).Dopo i caratteri US, occorrono altri due caratteri non specificati.In che modo si indicano caratteri non specifici in un'espressione regolare?Aspetta un attimo, lo sappiamo... ecco, ce l'abbiamo:ogni singolo carattere viene indicato da un punto (.).Logicamente, ciò significa che due caratteri possono essere indicati da due punti distinti:

..

OK, questo era facile.Proviamone uno più difficile.Immagina che i due caratteri interni indichino il paese dove è stata prodotta la parte.Se hai impianti di produzione negli Stati Uniti (US), nel Regno Unito (UK) e in Spagna (ES), significa che tutti questi codici a due caratteri sono validi:US, UK, ES.Come si può eseguire una scelta multipla in un'espressione regolare?

Beh, più o meno così:

objRegEx.Pattern = "^\d{4}(US|UK|ES).."

La chiave è questa piccola costruzione:(US|UK|ES).Abbiamo posizionato i tre valori accettabili (US, UK ed ES) all'interno dell'insieme di parentesi, separando ciascun valore con il carattere (|).Ecco come eseguire una scelta multipla con un'espressione regolare.

Ma, aspetta!Non abbiamo detto che si potevano inserire più opzioni nelle parentesi quadre?Tutto il discorso su [13579] non era per questo?Ovviamente sì.Tuttavia, questo si applica solo ai singoli caratteri; [13579] dovrà essere sempre interpretato come 1, 3, 5, 7 e 9. Per utilizzare 135 e 79 come scelte multiple, è necessario utilizzare questa sintassi:(135|79). Si possono utilizzare anche le parentesi per delineare una singola parola da cercare:

objRegEx.Pattern = "(scripting)"

Oppure, lasciar perdere le parentesi:

objRegEx.Pattern = "scripting"

Nota:OK, utile a sapersi, ma che succede se le parentesi devono essere incluse come parte di un termine da cercare; ad esempio, se si cerca "(script)"?Poiché le parentesi aperte e chiuse sono caratteri riservati nelle espressioni regolari, è necessario far precedere ogni carattere da \.In altre parole:

objRegEx.Pattern = "\(scripting\)"

Libertà di espressione

Questo è tutto per questo mese.Per ulteriori informazioni sulle espressioni regolari, puoi partecipare al webcast Teoria delle stringhe per gli amministratori di sistema:un'introduzione alle espressioni regolari (microsoft.com/technet/scriptcenter/webcasts/archive.mspx).Man mano che inizi a imparare, e a utilizzare, le espressioni regolari, ricorda sempre le immortali parole di Sofia Loren:"Gli errori sono parte del tributo che si paga per una vita vissuta in pieno".

Wow.Allora, gli Scripting Guys hanno vissuto vite davvero più piene!

Il rompicapo di script del Dottor Scripto

La sfida mensile che verifica non solo le tue capacità di risoluzione dei puzzle, ma anche le tue competenze di scripting.

Gennaio 2008:Sostantivi serpeggianti

Questo mese, il Dr. Scripto ha deciso di lavorare con Windows PowerShell.Ovviamente, non puoi lavorare con Windows PowerShell, o almeno non se lo usi correttamente (e Dr. Scripto fa sempre tutto per bene), senza i cmdlet.Per questo puzzle, Dr. Scripto nascosto alcuni cmdlet in una griglia. Il tuo compito è individuarli.

Ora, dobbiamo ammettere che questo puzzle sarebbe più complicato se dovessimo utilizzare l'intero cmdlet.A causa del costrutto verbo-sostantivo dei cmdlet, ne esistono a decine che iniziano con Get-, Set- e così via.Quindi, abbiamo tralasciato la parte verbale del cmdlet (e il trattino), lasciando solo i sostantivi(ma possiamo dirti che tutti i verbi iniziavano con "Get-").

L'attività di questo mese consiste nello scoprire dove sono i sostantivi dei cmdlet.Ti abbiamo fornito l'elenco di sostantivi nascosti nel puzzle(siamo davvero magnanimi, vero?).Ciascuna parola può essere scritta in senso orizzontale e verticale, in avanti o indietro, ma mai in diagonale.Ti forniamo la prima parola (Location) come esempio.Buona fortuna!

Elenco di parole

Alias
ChildItem
Credential
Date
EventLog
ExecutionPolicy
Location
Member
PSSnapin
TraceSource
Unique
Variable
WMIObject

ANSWER:

Il rompicapo di script del Dottor Scripto

Risposta:Sostantivi serpeggianti, gennaio 2008

Microsoft Scripting GuysGli Scripting Guys lavorano per Microsoft, o meglio... sono dipendenti Microsoft.Quando non si dedicano al baseball (o a varie altre attività) da giocatori, allenatori o semplici spettatori, gestiscono il TechNet Script Center.Consultare il documento su www.scriptingguys.com.

© 2008 Microsoft Corporation e CMP Media, LLC. Tutti i diritti riservati. È vietata la riproduzione completa o parziale senza autorizzazione.