Posts filed under 'programmazione'

Breve panoramica sulle espressioni regolari

La necessità di processare del testo è una tra le più ricorrenti tra le attività che ogni giorno svolgono gli sviluppatori: controllo dell’input utente, sostituzione di caratteri speciali, ecc. Per molti anni gli sviluppatori UNIX e Perl hanno avuto a disposizione un complesso, ma molto efficace, strumento: le Espressioni regolari.

Il linguaggio delle espressioni regolari è progettato e ottimizzato per la ricerca e la modifica del testo. Il linguaggio utilizza due tipi fondamentali di caratteri: caratteri effettivi e metacaratteri (più semplicemente, caratteri jolly). La capacità elaborativa delle espressioni regolari deriva dal set di metacaratteri.

Senza approfondire le tecniche più avanzate, come il Backreference, facciamo una panoramica generale di questo linguaggio di text-matching e di come è possibile utilizzarlo con profitto nelle nostre applicazioni.

L’uso più semplice di una espressione regolare è la verifica di una stringa con un pattern. Ad esempio, l’espressione regolare “nane” verifica con successo le stringhe “banane”, “nanerottola” e “xyznanexyz”, in quanto ognuna di queste stringhe contiene il pattern dell’espressione regolare; nessun carattere speciale è richiesto per un compito simile.

Se volessimo invece verificare che un pattern ricorra dal primo carattere di una determinata stringa dovremmo far precedere il nostro pattern dal carattere speciale “^”. Tornando all’esempio precedente, l’espressione regolare “^nane” verificherà con successo la stringhe “nanerottola” e “xyznanexyz”, ma non “banane”. Diversamente, se dovessimo verificare che il pattern ricorresse al termine della stringa, dovremmo utilizzare il carattere speciale “$”, così l’ espressione regolare “nane$” verificherà “banane”, ma non “nanerottola” e “xyznanexyz”, mentre l’espressione regolare “^nane$” verificherà solamente la stringa “nane” e nessun altra.

Tabella dei metacaratteri di posizione

^ Specifica che il pattern deve ricorrere esattamente all’inizio della stringa analizzata.
$ Specifica che il pattern deve ricorrere esattamente alla fine della stringa analizzata.
\A Specifica che il pattern deve ricorrere esattamente al primo carattere della stringa analizzata, e ignorare le righe multiple.
\Z Specifica che il pattern deve ricorrere esattamente alla fine dell’ultimo carattere della stringa analizzata, e ignorare le righe multiple.
\G Indica che il pattern deve ricorrere nel punto dove è terminato il pattern precedente.
\b Indica che il pattern deve ricorrere tra caratteri alfanumerici(\w), o non alfanumerici(\W)
\B Indica che il pattern non deve ricorrere tra caratteri alfanumerici(\w), o non alfanumerici(\W)

Notare che il linguaggio delle espressioni regolari è case-sensitive e spesso metacaratteri maiuscoli hanno significato opposto ai metacaratteri minuscoli. Inoltre è interessante notare che molti metacaratteri iniziano con il carattere “\”, chi sviluppa in C# dovrebbe ricordare di precedere ogni stringa che rappresenta un’espressione regolare con il carattere “@”, ad esempio:

Regex.IsMatch("pattern",@"\Apattern\Z");

Le espressioni regolari trovano particolare utilità anche per la verifica dei caratteri speciali, i quali non saranno ricercati in un semplice file di testo, tuttavia nella verifica di output generato da codice legacy o sistemi UNIX è un caso molto comune.

Tabella dei metacaratteri dei caratteri speciali

\a Specifica un carattere bell(allarme) \u0007.
\t Specifica un carattere tab(tabulazione) \u0009.
\r Specifica un carattere carriage return(ritorno a capo) \u000D.
\v Specifica un carattere vertical tab(tabulazione verticale) \u000B.
\f Specifica un carattere form feed(torna a inizio riga) \u000C.
\n Specifica un carattere new line(nuova linea) \u0009.
\e Specifica un carattere escape(annulla) \u001B.
40 Specifica un carattere ASCII in formato ottale di 3 cifre, ad esempio 40 rappresenta uno spazio.
\cC Specifica un carattere ASCII di controllo, ad esempio \cC rappresenta control-C.
\x20 Specifica un carattere ASCII in formato esadecimale di 2 cifre.
\ Quando precede un metacarattere, indica al processore di ignorare la sequenza di escape, ad esempio \* indica esattamente l’asterisco, \\ indica il backslash.

Le espressioni regolari trovano però la loro versatilità nella verifica di pattern più complessi, come i caratteri ripetuti o opzionali, ad esempio il simbolo “*” preceduto da un carattere indica 0 o più volte quel carattere, “+” indica invece 1 o più caratteri, per specificare un preciso numero di ripetizioni di un determinato carattere viene utilizzato un blocco “{n}”, dove n è il numero preciso di caratteri da ripetere. Allo stesso modo è possibile stabilire un range di valori per la ripetizione del carattere con il blocco “{n,m}”, dove n è il numero minimo, e m il massimo. Per includere un carattere opzionale si utilizza il simbolo “?”, per ogni singolo carattere il simbolo “.”. Per includere più caratteri vengono utilizzati dei blocchi “[xyz]“, dove “xyz” sono i caratteri opzionali, sempre nei blocchi di parentesi quadre si possono specificare anche range di set di caratteri, ad esempio “[a-n]“, indica che sono consentiti i caratteri dalla “a” alla “n”. Per specificare caratteri alternativi viene utilizzato il simbolo “|” ad esempio la sequenza “(a|ba)nane” indica o “anane” oppure “banane” indifferentemente.

Sequenze particolari

\d Indica una cifra. E’ equivalente alla sequenza [0-9].
\D Indica un carattere non cifra. E’ equivalente alla sequenza [^0-9].
\s Indica un qualsiasi carattere di spazio, inclusi tabulazioni e form-feed. E’ equivalente alla sequenza [\f\n\r\t\v].
\S Nega il precedente.
\w Indica un qualsiasi carattere letterale, incluso underscore. E’ equivalente alla sequenza [A-Za-z0-9_].
\W Nega il precedente.

Naturalmente l’utilizzo delle espressioni regolari non si limita al crudo matching delle stringhe, e questo articolo non è riuscito neppure a grattare la superficie di un argomento tanto vasto, numerosissimi testi sono stati scritti in proposito. Ho scritto questa breve panoramica in quanto mi sto preparando all’esame 70-536 e il fatto di aver sempre snobbato le Regular Expression mi fa capire quanto spesso ci ostiniamo a evitare la soluzione più semplice, quando la soluzione ottimale c’è e richiede solo il necessario sforzo per essere padroneggiata. Siccome le sequanze di escape sono molte e la mia memoria è terribile o scritto questo semplicissimo tool che potrebbe essere utile per esercitarsi nella costruzione delle espressioni regolari più semplici.

1 comment Agosto 15, 2008

Web Services ASP.NET & Google API

SOA (Architetture Orientate ai Servizi) è più di una parola, è anche un efficace modello di progettazione, che è possibile utilizzare per risolvere molti problemi di sviluppo.

Al centro di SOA troviamo i servizi Web, che sono componenti modulari di software utilizzati su Internet che comunicano utilizzando standard XML.

Google, che non ha bisogno di presentazioni, ha rilasciato Web API che consentono agli sviluppatori di accedere ad alcune funzionalità utilizzando servizi Web.

Le API permettono di usare Simple Object Access Protocol (SOAP) e Web Services Description Language (WSDL) per effettuare una query su più di 8 miliardi di pagine Web.

In questo breve articolo esamineremo come sfruttare la potenza del motore di ricerca di Google, ma discuteremo anche su alcuni dei principi fondamentali alla base di servizi Web in

Prima di usare le API Web di Google, è necessario seguire una serie di passaggi.

In primo luogo, è necessario disporre di una connessione a Internet, oltre a una linguaggio di sviluppo in grado di interfacciarsi con i servizi Web. Per questo articolo, useremo C # e Visual Studio. NET, ma i servizi Web sono per natura molto flessibili, così si potrebbe anche utilizzare Java, Perl, C + +, o qualsiasi altro linguaggio desideriate.

In secondo luogo, è necessario scaricare il Google API SDK e creare un account con Google.

È necessario disporre di un account, perché è necessario un generatore di chiavi di licenza per accedere a Google Web API.

La versione delle API utilizzate in questo articolo è la beta1, questo implica alcune limitazioni. Ad esempio, il limite di risultati per ogni query è 10, e un limite di 1000 query al giorno.

Prima di considerare una soluzione si dovrebbe consultare la concessione di licenze relativa.

Dunque, dopo aver sottoscritto un account e aver ricevuto una chiave di licenza di Google, apriamo Visual Studio .NET e creiamo un nuovo progetto web ASP.NET.

In primo luogo creiamo uno user control che costituirà la GUI per l’esempio, ciò ci consentirà di concentrarci sulla logica in maniera più efficiente senza dover saltare continuamente tra modalità codice e design.

Dopo aver creato un nuovo user control ASCX, aggiungiamo una tabella HTML che conterrà 5 Label:

  • Ricerca di base
  • Restrizione al dominio di un sito
  • Filtro su file
  • Da
  • Fino a

5 TextBox:

  • txtBasic
  • txtSiteRes
  • txtFilter
  • txtFromDate
  • txtToDate

E un unico pulsante di ricerca: btnSearch.

Successivamente inseriamo una GridView(dgResult) e quindi aggiungiamo altre due Label che chiameremo lblResults e lblError.

Successivamente, trascinare e rilasciare una banca dati griglia dgResults chiamato dal tuo strumenti, quindi aggiungere altri due etichette di sopra della griglia chiamato lblResults e lblError.

Nel mio esempio, ho aggiunto qualche stile per le etichette, e ho aggiunto un calendario popup javascript per i campi data.Tuttavia, la funzione è sempre più importante della forma, percui l’aspetto grafico non sarà oggetto della nostra trattazione.

Ora che la GUI è pronta, possiamo proseguire nell’ approfondire le funzionalità fondamentali di questo controllo. Ma prima di iniziare la scrittura del codice, Discutiamo rapidamente su alcuni dei principi fondamentali alla base dei servizi Web e la loro attuazione in . NET Framework. I Servizi web sono fondamentalmente programmi riutilizzabili esposti a Internet che utilizzano una struttura standard di messaggistica. I Servizi web generalmente utilizzano SOAP per la loro struttura di messaggistica. SOAP è uno protocollo standard basato su XML che definisce l’uso di XML e HTTP per l’accesso ai servizi Web indipendentemente dalla piattaforma utilizzata. A meno che non abbiate tenuto la testa sepolta nella sabbia per gli ultimi anni, probabilmente avete sentito su tutti parlare di servizi Web. Ciò che invece potrebbe non essere chiaro, tuttavia, è che il paradigma dei servizi Web è unico poiché ogni servizio Web (quando costruito correttamente) è auto-descrittivo. Vale a dire, si possono comprendere le sue funzionalità e le sue interfacce esaminando i metadati del servizio Web, ovvero il documento che lo descrive, secondo le specifiche WSDL (Web Services Description Language).

Bene, a questo punto possiamo cominciare.

In primo luogo, aggiungere un riferimento alle Google API facendo clic destro sulla cartella Riferimenti e selezionare Aggiungi riferimento Web.

Aggiungiamo http://api.google.com/GoogleSearch.wsdl” per il campo URL.

Ora possiamo riferirci alle Google API, come per ogni altro componente gestito attraverso la dichiarazione dello spazio dei nomi utilizzando una dichiarazione “using”, o di un’istanza, e così via. E’ possibile modificare il nome di un riferimento Web semplicemente cambiando il nome della cartella nella finestra Proprietà.

Un riferimento web(web-reference) non è altro che una classe proxy autogenerata, che potete trovare nella vostra directory Project, sotto la cartella WebReference. Siate consapevoli del fatto che quando cambiate il nome della proprietà, state anche cambiando il modo in cui si fa riferimento all’API nel codice (vale a dire, il namespace utilizzato dallo statement “using”).

Il nome di default di riferimento per Google API è “com.google.api” e così è utilizzato in questo esempio.

Troverete Reference.cs, GoogleSearch.wsdl, e Reference.map nella Directory WebReference .

L’IDE . NET sostanzialmente astrae tutti i servizi Web e le interfacce proxy per voi quando si aggiunge un riferimento in questo modo. Ma molti di noi geek piace vedere cosa succede sotto le coperte, così ecco un’occhiata a un pezzo di codice generato per la classe proxy.

[System.Web.Services.Protocols.SoapRpcMethodAttribute

("urn:GoogleSearchAction", RequestNamespace="urn:GoogleSearch", ResponseNamespace="urn:GoogleSearch")]

[return: System.Xml.Serialization.SoapElementAttribute("return")]

public GoogleSearchResult doGoogleSearch(string key, string q, int start, int maxResults, bool filter, string restrict, bool safeSearch, string lr,string ie, string oe)

{

object[] results = this.Invoke(“doGoogleSearch”, new object[] {key, q, start, maxResults, filter, restrict, safeSearch, lr, ie, oe});return ((GoogleSearchResult)(results[0]));

}

Come si può vedere, il codice del proxy codice non serve ad altro che a trovare le informazioni nel file WSDL, ma permette inoltre di interagire con un servizio Web come se fosse un oggetto gestito sulla nostra macchina locale. Per la maggior parte, il codice proxy codice generato da . NET è identico al codice generato dallo strumento WSDL.exe utilizzabile dalla riga di comando.Una volta aver ottenuto un riferimento web alle API di Google, è possibile istanziare semplicemente un oggetto GoogleSearchService che ha tre metodi principali:doGoogleSearch, doGetCached, e doSpellingSuggestion. . NET genera anche un wrapper di metodi asincroni per ogni firma di metodo presente nel WSDL.Sarebbe impossibile coprire interamente tutte le funzionalità delle API di Google in questo articolo, noi ci concentreremo sul metodo doGoogleSearch e come si può usare nelle nostre applicazioni. Vediamo come fare una ricerca base:

/ / Crea un oggetto di Google

object GoogleSearchService gss = new GoogleSearchService();

/ / Richiama il metodo di ricerca

GoogleSearchResult results = gss.doGoogleSearch(“Nostra_Chiave_Licenza”, “Nostra_Query”, 0, 10, false, string.Empty, false, string.Empty, string.Empty, string.Empty);

Il metodo DoGoogleSearch restituisce un oggetto GoogleSearchResult, utilizzabile come un container per i risultati restituiti da Google. Strettamente connessa alla classe GoogleSarchResult è la classe ResultElement, che si utilizza per avere accesso ai dati restituiti.

La classe ResultElement è fondamentalmente una matrice che permette di accedere a questi membri: cachedSize, directoryCategory, directoryTitle, hostname, relatedInformationPresent, snippet, riassunto, titolo, e l’URL.

Come per la maggior parte delle applicazioni, il codice per la getione degli errori non si scrive da sé; è necessario dunque aggiungere un meccanismo di trapping , con un semplice blocco try/catch. Con i servizi Web, è necessario gestire un particolare tipo di eccezione chiamato System.Web.Services.Protocols.SoapException, perché un errore che si verifica all’interno di un servizio Web viene sollevato come eccezione SOAP per una maggiore interoperabilità. Piuttosto che mettere tutto il codice nel Button, ho incapsulato il controllo della funzionalità di questi metodi: BuildQuery, per la stringa di ricerca; FormatResults,che restituisce i risultati; ShowErrorMessage, che visualizza gli errori e GoogleHandler, che è l’interfaccia principale chiamata dal pulsante.

C # • incapsulare le API Web di Google

Utilizzare il controllo utente GoogleIt. NET per accedere alle API di Google. GoogleIt utilizza metodi di aiuto per la costruzione della stringa di ricerca, formattazione dei risultati in una GridView, e la visualizzazione di errori nel GUI. Il codice seguente è una versione condensata.

public class GoogleIt : System.Web.UI.UserControl

{

// E’ necessaria una chiave di licenza per avere accesso alle funzionalità di Google API

private const string LICENSE_KEY = “Chiave_Licenza”;

private void btnSearch_Click(object sender, System.EventArgs e)

{

try

{ GoogleHandler(); }

catch (System.Web.Services.Protocols.SoapException ex)

{ ShowErrorMessage(ex.ToString(),true); }

catch (System.Exception ex){ ShowErrorMessage(ex.ToString(),true); }

}

private void GoogleHandler()

{

// Create a Google Search object

GoogleSearchService gss = new GoogleSearchService();

// Invoca il metodo di ricerca

GoogleSearchResult results = gss.doGoogleSearch(LICENSE_KEY, BuildQuery(), 0, 10, false, string.Empty, false, string.Empty, string.Empty, string.Empty);

// Visualizza il numero di risultati della ricerca

lblResults.Text = “Results Found: ” + results.estimatedTotalResultsCount;

lblResults.Visible = true;

DataTable table = new DataTable();

DataColumn col1 = new DataColumn(“Results”, typeof(string));

table.Columns.Add(col1);

int pointer = 0;

while(pointer<results.resultElements.Length)

{

DataRow row = table.NewRow();

row[0] = FormatResults(results.resultElements[ pointer]);

table.Rows.Add(row);

pointer ++;

}

dgResults.DataSource = table;

dgResults.DataBind();

}

private void ShowErrorMessage(string msg, bool bShow)

{

if (bShow == true)

{

lblError.Text = “<br>” + msg;

lblError.Visible = true;

}

else

{ lblError.Visible = false; }

}

private string BuildQuery()

{

StringBuilder query = new StringBuilder();

if(txtBasicSearch.Text.Length > 0)

query.Append(txtBasicSearch.Text);

else

throw new Exception( “Devi specificare un criterio base di ricerca”);

if(txtSite.Text.Length > 0)

{

query.Append(” site:”);

query.Append(txtSite.Text);

}

if(txtFilter.Text.Length > 0)

{

query.Append(” filetype:”);

query.Append(txtFilter.Text);

}

string txtDateFrom = Request.Form.Get(“txtDateFrom”);

string txtDateTo = Request.Form.Get(“txtDateTo”);

if(txtDateFrom.Length > 0 && txtDateTo.Length > 0)

{

// Find the GregToJulian() method

string fromDateJul = GregToJulian(txtDateFrom);

string toDateJul = GregToJulian(txtDateTo);

query.Append(” daterange:”);

query.Append(fromDateJul);

query.Append(“-”);

query.Append(toDateJul);

}

return query.ToString();

}

private string FormatResults(ResultElement resultToFormat)

{

StringBuilder sb = new StringBuilder();

sb.Append(“<p><b><u><a href=”);

sb.Append(resultToFormat.URL);

sb.Append(” target=new>”);

sb.Append(resultToFormat.title);

sb.Append(“</a></u></b></p>”);

sb.Append(“<p>”);

sb.Append(resultToFormat.snippet);

sb.Append(“<br>”);

sb.Append(resultToFormat.URL);

sb.Append(“ ”);

sb.Append(resultToFormat.cachedSize);

sb.Append(“</p>”);

return sb.ToString();

}

}

}

Effettuiamo una ricerca di base per il termine “MSMQ”, si potrà osservare ritornare un numero molto alto di risultati, ma si possono visualizzare solamente i primi 10 risultati di questi dati nella vostra GridView.

Query avanzate

Ora che si può fare una ricerca base, potreste chiedervi in quale modo questo potrebbe aiutarvi nelle vostre attività quotidiane di sviluppo Web. Ebbene, le API di Google offrono molto più che la sola funzionalità di ricerca di base. Si puòlimitare la ricerca ad un solo sito, ad una sola estensione di documento, o un intervallo di date, per citare solo alcune funzioni,Google API Web offre anche la possibilità di restringere i risultati per una particolare nazione e/o di una lingua specifica. Questo è facilmente realizzabile con il passaggio di altri parametri stringa al metodo doGoogleSearch:

/ / Filtro per nazione Germania

/ / Filtro per lingua

GoogleSearchResult results = gss.doGoogleSearch(“Your License Key”, “Your Query”, 0, 10, false, “countryDE”, false, “lang_de”, string.Empty, string.Empty);

Esaminiamo più da vicino alcune di queste ricerche avanzate e come si possono utilizzare nelle vostre applicazioni. L’unico settore nel esempio della nostra GUI che è veramente necessario è txtBasicSearch, ma diciamo che si desidera limitare la ricerca ad un particolare sito, ad esempio, www.aspitalia.com. Si può conseguire questo semplicemente concatenando “site: www.aspitalia.com” alla fine della vostra ricerca di base.BuildQuery e il metodo costruirà la stringa di ricerca che si passa nel metodo doGoogleSearch.

Ad esempio, diciamo che stiamo effettuando una ricerca per MSMQ, e si desidera restringere la ricerca a www.aspitalia.com. Immettere “MSMQ” in txtBasicSearch, quindi immettere www.aspitalia.com in txtSite. Dopo aver eseguito la ricerca, si noterà che il numero di risultati restituiti si è ristretto enormemente. È possibile estendere questa funzionalità di ricerca a qualsiasi sito Web, come ad esempio il tuo blog o al sito web della vostra azienda (si prega di consultare l’accordo di licenza prima di uso in produzione).

Il filtraggio per estensione o per data funziona alla stessa maniera. Ad esempio, è possibile cercare solo alcuni tipi di documento concatenando “filetype: pdf” alla fine della ricerca di base, che limiti i risultati ai documenti in formato PDF. Il filtraggio per data, anche se formattato allo stesso modo, necessita però di un accorgimento, dovuto al formato che la data deve possedere, il formato di data Giuliana. Il calendario Giuliano parte dal 1 ° gennaio 4713 aC. Dopo aver generato la data Giuliana “a” e “da” , il formato della stringa di ricerca va concatenato allo stesso modo “daterange: <start_date> – <end date>” alla fine della vostra stringa di ricerca di base.

È possibile estendere ulteriormente le funzionalità di Google API mediante la combinazione di una qualsiasi di queste parametrizzazioni. Ad esempio, è possibile limitare la ricerca a un sito Web, filtramdo per un determinato tipo di documento, e di limitare l’intervallo di date, tutti nella stessa stringa di ricerca. Questo articolo ha solo graffiato la superficie delle funzionalità di Google API. Ci sono molte altre funzionalità che è possibile utilizzare nelle applicazioni, tra cui il controllo ortografico, la cache di ricerca, e altro ancora.

3 comments Luglio 14, 2008

Pattern & Practices Guidance Explorer

Come ben sa chi come me frequenta assiduamente i newsgroup Microsoft e i forum su Asp.Net non è raro incontrare richieste sul modo migliore di affrontare un determinato problema. Nel processo di analisi che precede lo sviluppo di una nuova applicazione poter contare su collaudate linee guida significa partire con il piede giusto ed esporci meno a problemi futuri durante lo sviluppo o peggio in fase di test.
L’area del sito di MSDN di Microsoft, Pattern & Practices viene in aiuto degli sviluppatori in questo senso con ampia documentazione sugli scenari più vari.
Per chi può considerare utile un tool per usufruire di questa documentazione anche quando non siamo connessi a Internet:

patterns & practices Guidance Explorer

Esiste anche una versione Online per chi non vuole o non può installare software:

Guidance Explorer Web

Il tool è ben realizzato, permette la sincronizzazione per l’aggiornamento dei contenuti e numerose funzionalità di subsetting, anche se lamenta qualche difetto di progettazione dei controlli; da provare…

Add comment Giugno 16, 2008

Previous Posts


Cloud delle categorie

aspnet Framework .net hosting illustrazione off topic programmazione recensioni Tips tutorial web-design

Articoli Recenti

Archivi

Statistiche del Blog

Vota questo maledetto blog

Social Bookmarking

Da dove diavolo arrivate…

RSS Feed da StackTrace

RSS Feed AspItalia ASP.NET 2.0