2014-06-06 11 views
5

All'interno di una stringa, sto tentando di aggiornare più istanze della stessa parola con valori diversi.Sostituzione di ogni istanza di una parola in una stringa con un valore univoco

Questo è un esempio eccessivamente semplificato, ma data la seguente stringa:

"The first car I saw was color, the second car was color and the third car was color" 

La prima istanza della parola colore voglio sostituire con "rosso", la seconda istanza dovrebbe essere "verde" e la terza istanza dovrebbe essere "blu".

Quello che ho pensato di provare era un pattern regex per trovare parole limitate, interagire attraverso un ciclo e sostituirli uno alla volta. Vedi il codice di esempio qui sotto.

var colors = new List<string>{ "reg", "green", "blue" }; 
var sentence = "The first car I saw was color, the second car was color and the third car was color"; 

foreach(var color in colors) 
{ 
    var regex = new Regex("(\b[color]+\b)"); 
    sentence = regex.Replace(sentence, color, 1); 
} 

Tuttavia, la parola "colore" non viene mai sostituita con il nome del colore appropriato. Non riesco a trovare quello che ho fatto di sbagliato.

risposta

3

Prova un delegato della partita.

È un sovraccarico di Regex.Replace() a cui manca la maggior parte della gente. Ti consente semplicemente di definire un gestore dinamico potenzialmente sensibile al contesto anziché una stringa codificata in modo tale da poterlo sostituire e potrebbe avere effetti collaterali. Il "i ++%" è un operatore modulo che viene utilizzato di seguito per scorrere semplicemente i valori. Potresti usare un database o una tabella hash o altro.

var colors = new List<string> { "red", "green", "blue" }; 
var sentence = "The first car I saw was color, the second car was color and the third car was color"; 
int i = 0; 
Regex.Replace(sentence, @"\bcolor\b", (m) => { return colors[i++ % colors.Count]; }) 

Questa soluzione funziona per un numero arbitrario di sostituzioni, che è più tipico (sostituzione globale).

+0

Questo ha fatto il trucco. –

+0

Questo è un adorabile delegato, vedo che non sei estraneo al tag 'regex'. :) – zx81

+0

@ zx81: Grazie! Sì, nella mia esperienza, la maggior parte della gente non si rende nemmeno conto che la libreria .NET di Regex supporta un delegato della partita. Anche se preferisco le regex implementate come sintassi piuttosto che come API, come Perl. È quello che ho fatto con Cola in realtà, anche se non ho ancora deciso come mappare l'idioma dei delegati regex alla sintassi. – codenheim

1

Cerco di stare lontano da Regex quando possibile. E ha il suo posto, ma non per i casi semplici come questo IMHO :)

public static class StringHelpers 
{ 
    //Copied from http://stackoverflow.com/questions/141045/how-do-i-replace-the-first-instance-of-a-string-in-net/141076#141076 
    public static string ReplaceFirst(this string text, string search, string replace) 
    { 
     int pos = text.IndexOf(search); 
     if (pos < 0) 
     { 
      return text; 
     } 
     return text.Substring(0, pos) + replace + text.Substring(pos + search.Length); 
    } 
} 


var colors = new List<string>{ "red", "green", "blue" }; 
string sentence = colors.Aggregate(
    seed: "The first car I saw was color, the second car was color and the third car was color", 
    func: (agg, color) => agg.ReplaceFirst("color", color)); 
+0

Downvoter, perché il downvote? –

2

Il problema è che nel tuo esempio, color non è sempre preceduta e seguita da un carattere non di parola. Per la vostra ad esempio, questo ha funzionato per me:

var regex = new Regex("\b?(color)\b?"); 

Quindi questo:

var colors = new List<string>{ "red", "green", "blue" }; 
var sentence = "The first car I saw was color, the second car was color and the third car was color"; 

foreach(var color in colors) 
{ 
    var regex = new Regex("\b?(color)\b?"); 
    sentence = regex.Replace(sentence, color, 1); 
} 

Produce il seguente:

La prima auto che ho visto era rossa, la seconda auto era verde e la terza auto era blu

+1

'\ b?' È superfluo - o è un limite di parole, o non lo è - potrebbe anche usare '" (color) "' –

+0

E 'stato. Grazie! –

+0

@UriAgassi Non voglio discutere con te, mi piacerebbe davvero utilizzare Steven Wexler's [risposta] (http://stackoverflow.com/a/24089785/1346943) –

Problemi correlati