Come evitare di chiamare String.Replace () in un ciclo?

3

Sto costruendo un semplice sistema di gestione e-mail in C #, e funziona in modo sorprendente, ma ho un problema personale con il modo in cui l'ho progettato:

Il modello assomiglia a questo:

Hello {UserName},
Welcome to ....

E il modo in cui sto sostituendo i token con i valori è questo:

foreach (var variable in variables)
{
    str = str.Replace("{" + variable.Key + "}", variable.Value);
}

A dir poco, lo odio. Esiste un modo più efficiente di gestire i token?

UPDATE: trovato questo articolo e sembra che sia REGEX sia StringBuilder siano più lenti di String.Replace ();

StringBuilder.Replace VS REGEX.Replace vs String.Replacte

    
posta Alexus 25.06.2015 - 02:07
fonte

2 risposte

9

Non penso che tu abbia bisogno di token.

Un modo possibile per migliorare le cose è guardare ogni carattere in input del testo (i modelli) solo una volta.

Cerca la stringa dall'inizio alla fine (una volta) e assembla una nuova stringa come segue: dall'inizio cerca {, seguito dai caratteri identificativi, quindi}. Sposta il testo della stringa prima di {nella nuova stringa, quindi cerca l'identificatore in un dizionario e sposta la sostituzione nella nuova stringa. Ricomincia a cercare {da dove avevi interrotto l'ultima volta.

In questo modo non stai effettuando la scansione del testo di input più e più volte. Potresti tokenizzare la stringa di input, ma non credo che sia d'aiuto rispetto a questo suggerimento.

Il punto qui è pensare a come le cose vanno in scala (si pensi alle descrizioni di O ()). Se alcuni modelli sono molto grandi, stai scandendo quel testo una volta per ogni operazione str.Replace. Inoltre, se il numero di variabili è molto grande, si esegue la scansione di un testo di input di grandi dimensioni tante volte quante sono le variabili. Con questo suggerimento, si esegue la scansione del testo di input solo una volta, indipendentemente dal numero di variabili.

    
risposta data 25.06.2015 - 02:18
fonte
4

Un altro modo per risolverlo è usare le espressioni regolari:

string LookupVariable(Match match) {
   string name = match.Groups[1].Value;
   return variables[name];
}

str = (new Regex("{([^}]*)}")).Replace(str, LookupVariable);

In realtà non codifico C #, quindi la mia sintassi non ha quasi certamente ragione.

    
risposta data 25.06.2015 - 05:45
fonte

Leggi altre domande sui tag