Regex & Lambda

Prima della cura:

private static string FormatLinks(string input, bool insideLink)

{

    MatchCollection matches = inlineUrls.Matches(input);

    if (matches.Count == 0)

    {

        return input;

    }

 

    StringBuilder sb = new StringBuilder(input.Length * 2);

 

    int inputIndex = 0;

    foreach (Match tag in matches)

    {

        // add the normal text between the
        // current index and the index of the current tag

        if (inputIndex < tag.Index)

        {

            sb.Append(input.Substring(inputIndex, tag.Index - inputIndex));

        }

 

        string url = tag.Value;

 

        sb.AppendFormat(insideLink ? "{1}" :
         "<a target='blank' href='{0}'>{1}</a>", url,
         HtmlHelper.ReduceUrlLength(url, maxUrlLength));

        inputIndex = tag.Index + tag.Length;

    }

 

    // add remainder

    if (inputIndex < input.Length)

    {

        sb.Append(input.Substring(inputIndex));

    }

 

    return sb.ToString();

}

Dopo la cura

private static string FormatLinks(string input, bool insideLink)

{

    return inlineUrls.Replace(input, m =>

        {

 

            return String.Format(insideLink ?
           "{1}" : "<a target='blank' href='{0}'>{1}</a>",
             m.Value,
            HtmlHelper.ReduceUrlLength(m.Value, maxUrlLength));

        }

    );

}

Interessante anche il fatto che, sebbene normalmente le lambda siano meno leggibili, nel caso specifico la riduzione di codice ridondante rende l’intenzione più evidente.

-quack

P.S. è un periodo in cui sniffo RegEx da mattina a sera; dienticavo: grazie all’enorme lavoro di refactoring i link nella nuvoletta sono ora cliccabili, per la gioia di Dovella

Potrebbero interessarti anche:
Commenti (18):
1. Dovella Win 98
venerdì 3 luglio 2009 alle 7:42 PM - firefox 2.0.0.20 Windows 98
   

Me ne sono accorto subito stamattina

PS. hai visto il post in OT con WM e Opera?

 

PS PS- dai che oggi dovrebbe essere il grande giorno (spero)

sennò piglioo a capate il Postale

   
2. Paperino
venerdì 3 luglio 2009 alle 7:47 PM - firefox 3.5 Windows 7
   

PS- dai che oggi dovrebbe essere il grande giorno

Lo spero anche io visto che sono a casa e le raccomandate vanno firmate

   
3. Phenix
venerdì 3 luglio 2009 alle 9:20 PM - chrome 2.0.178.0 Windows 7
   

Avessi capito una riga di codice sarei felice!

   
4. Edward
venerdì 3 luglio 2009 alle 9:56 PM - firefox 3.5 Windows 7
   

@ Phenix

Converte l'indirizzo di un sito (es tiziocaio&sempronio.com) ed il nome associato (Il triumvirato) nel codice html corrispondente (< a traget='blank' href='tiziocaio&sempronio.com' >Il triumvirato< /a >, senza spazi prima e dopo i bracket).

Faccio notare che gia' la prima implementazione e' molto piu' elegante di quella che scriverei io, la seconda non ha confronto

Unico dubbio: se scrivo

if (matches.Count > 0)

    {

        catch fire;

    }

devo chiamare i pompieri?

 

Edward

   
5. Phenix
venerdì 3 luglio 2009 alle 10:57 PM - chrome 2.0.178.0 Windows 7
   

Grazie Edward, sarà che di C# sono completamente a digiuno, mai scritta una riga di codice! Solo qualche modestissima cosa in Java per l'università...

   
6. Edward
venerdì 3 luglio 2009 alle 11:49 PM - firefox 3.5 Windows 7
   

@ Phenix:

Io non conosco il C# e mastico pochissimo Java (una mentina o poco piu' ): a intuito dovrebbe convertire gli indirizzi, ma posso sempre sbagliarmi.

 

Edward

   
7. Luigi Bruno
sabato 4 luglio 2009 alle 12:27 AM - IE 8.0 Windows Vista
   

Non esiste limite al refactoring o all'ottimizzazione spinta?

   
8. 0verture
sabato 4 luglio 2009 alle 1:09 AM - firefox 3.5 Windows XP
   

La demenza senile o un ictus

   
9. Daniele B.
sabato 4 luglio 2009 alle 10:23 AM - firefox 3.5 Windows 7
   

@0verture:

LOL, a momenti sputavo il caffè per il tuo commento!

   
10. Pinco
sabato 4 luglio 2009 alle 11:06 AM - chrome 523.12.2 Android 1.0
   
@overture

Ahahahhahahahahhahahahaha

   
11. il nonno
sabato 4 luglio 2009 alle 3:40 PM - chrome 2.0.172.28 Windows Vista
   

Paperino, esempio molto istruttivo, sarebbe bello capire se questo tipo di refactoring ha impatto sulle performance.

Nella versione "prima della cura" fai prima un match per estrarre dalla lista solo gli Urls che corrispondono all'input e poi per ognuno di questi match applichi la trasformazione del caso.

Nella versione "dopo la cura" viene fatto un replace per ogni Urls, ma non ho idea se lo string.Format venga eseguito solo per le Urls che matchano l'input o venga fatto per tutti gli Urls (chiaramente dove non c'e' match il replace non fa alcun replace).

Non e' che nella versione "cool" si fanno cose "evitabili" e quindi con un impatto sulle performance? Magari nell'esempio specifico l'impatto non e' significativo ma in generale c'e' questo problema con questo tipo di refactoring?

 

   
12. Paperino
sabato 4 luglio 2009 alle 5:05 PM - firefox 3.5 Windows 7
   

@nonno:

La semantica di RegEx.Replace è quella di invocare la funzione delegate solo per le stringhe da rimpiazzare, quindi i due pezzi di codice sono praticamente identici. L'unico overhead nel secondo caso è il costo di invocazione del metodo che non è gratuito. Sarebbe interessante misurare, lo farò con calma.

   
13. Paperino
sabato 4 luglio 2009 alle 5:41 PM - firefox 3.5 Windows Vista
   

5000 iterazioni, diverse esecuzioni con risultati in linea.

Iterativo Millisecs: 15608
Lambda Millisecs: 16419

5% circa. Secondo me vale assolutamente la pena. O no?

 

   
14. il nonno
sabato 4 luglio 2009 alle 5:46 PM - chrome 2.0.172.28 Windows Vista
   

Vale!

Dovro' studiarmele bene 'ste espressioni lambda, sono decisamente interessanti

   
15. wisher
sabato 4 luglio 2009 alle 8:18 PM - chrome 2.0.181.1 Windows Vista
   

C'è un problema con la visualizzazione dell'immagine: aovestdipaperino.com/blog/smileys/confused.gif nel riquadro dei pensieri di Paperino.

Mi sa che ti tocca giocare ancora un po' con le RegExp

   
16. Paperino
sabato 4 luglio 2009 alle 9:03 PM - firefox 3.5 Windows 7
   

Good catch wisher, oggi mi 'riposo' però

   
17. 0verture
sabato 4 luglio 2009 alle 9:06 PM - firefox 3.5 Windows XP
   

A prima vista si direbbe che il secondo codice è più ottimizzato del primo però guardato dal punto di vista di qualcuno che dovrebbe implementare un simile codice in un sistema embedded quindi dotato di poca memoria, se si dovessero riscrivere entrambi i codici senza far uso di librerie e funzioni già pronte, quale sarebbe il più compatto ?

   
18. Paperino
sabato 4 luglio 2009 alle 9:55 PM - firefox 3.5 Windows Vista
   

@wisher:

ho errato nell'ordine di applicazione dei filtri (prima vanno convertite le URL e poi gli smiley), però il risultato non avrebbe dovuto essere così disastroso.

Il baco è sistemato ma dentro di esso c'è nascosto un baco più piccolo che aspetta di venire fuori. Se non ci dormo lo scovo...

   
Lascia un commento:
Commento: (clicca su questo link per gli smiley supportati; regole di ingaggio per i commenti)
(opzionale, per il Gravatar)