Domanda

Date le seguenti stringhe di input e di espressioni regolari:

const string inputString = "${Principal}*${Rate}*${Years}";
const string tokenMatchRegexString = @"\${([^}]+)}";

Come posso sostituire ogni token (cioè $ {} Principal, $ {} Tasso, e $ {} anni) con il valore di ritorno della mia funzione 'ReplaceToken'?

private static string ReplaceToken(string tokenString)
{
    switch (tokenString)
    {
        case "Principal":
            return GetPrincipal();
        case "Rate":
            return GetRate();
        case "Years":
            return GetYears();
        default:
            throw new NotImplementedException(String.Format("A replacment for the token '{0}' has not been implemented.", tokenString));
    }
}

private static string GetPrincipal()
{
    throw new NotImplementedException();
}

private static string GetRate()
{
    throw new NotImplementedException();
}

private static string GetYears()
{
    throw new NotImplementedException();
}
È stato utile?

Soluzione

Regex ha un sovraccarico che prende un MatchEvaluator. L'ingresso è una partita, e restituisce una stringa. Il valore della Partita in questo caso sarebbe l'intero modo, così si potrebbe creare uno spessore che estrae il valore (si sta già catturando all'interno del tuo Regex) e si adatta al metodo che hai postato.

Regex.Replace(inputString,
              tokenMatchRegexString,
              match => TokenReplacement(match.Groups[1].Value));

Altri suggerimenti

Se davvero basta un piccolo numero di gettoni per sostituire che si sa prima del tempo, è possibile utilizzare string.Replace() per sostituire solo i token uno per uno. Questa semplice tecnica può funzionare, ma ha inconvenienti. Non è particolarmente estensibile, può tradursi in (usa e getta) stringhe intermedi, e può anche provocare il codice confuso.

Se si aspetta di avere molti segni diversi e hanno regole di corrispondenza coerenti, è possibile utilizzare Regex.Replace() che prende un delegato MatchEvaluator - essenzialmente la funzione che accetta un regolare le partite di espressione e restituisce una stringa per sostituire la partita con. Il vantaggio di utilizzare l'overload Replace() che prende un MatchEvaluator è che aiuta a evitare la creazione di stringhe intermedi che vengono poi utilizzati per sostituire solo la prossima partita. E 'anche bello riutilizzare built-in classi .NET, piuttosto che rotolare il proprio.

Infine, se avete requisiti partita / sostituzione in realtà complesse, è possibile utilizzare librerie come StringTemplate per fare più complessa espansioni modello e partita di sostituzione.

Ecco un esempio di utilizzo della chiamata Regex.Replace():

const string inputString = "${Principal}*${Rate}*${Years}";
const string tokenMatchRegexString = @"\${([^}]+)}";

var rex = new Regex( tokenMatchRegexString );
MatchEvaluator matchEval = match => TokenReplacement( match.Groups[1].Value );

rex.Replace( inputString, matchEval );

Non reinventare la ruota. Io uso StringTemplate (la C # versione) quando fare le cose in questo modo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top