C # Regex: Como posso substituir fichas com cadeias de caracteres geradas em tempo de execução?

StackOverflow https://stackoverflow.com/questions/1869567

Pergunta

Dado o seguinte entrada e cordas regex:

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

Como posso substituir cada token (ou seja, $ {principal}, $ {Taxa} e $ {} anos) com o valor de retorno da função meu '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();
}
Foi útil?

Solução

Regex tem uma sobrecarga que leva um MatchEvaluator. A entrada é um jogo, e ele retorna um string. O valor do jogo, neste caso, seria de toda a forma, para que você possa criar um calço que extrai o valor (você já está capturando-o dentro de sua Regex) e adapta-se ao método que você postou.

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

Outras dicas

Se você realmente só tem um pequeno número de tokens para substituir que você sabe antes do tempo, você pode usar string.Replace() apenas para substituir as fichas uma a uma. Esta técnica simples pode trabalhar, mas tem desvantagens. Não é particularmente extensível, que pode resultar em (descartáveis) cordas intermediários, e também pode resultar em confundir código.

Se você espera ter muitos símbolos diferentes e têm regras de correspondência consistente, você poderia usar Regex.Replace() que leva um delegado MatchEvaluator - essencialmente função que aceita uma jogos de expressão regular e retorna uma string para substituir o jogo com. A vantagem de usar a sobrecarga Replace() que leva um MatchEvaluator é que ele ajuda a evitar a criação de cadeias de intermediários que são então utilizados apenas para substituir o próximo jogo. Também é bom para reutilizar built-in classes de .NET, em vez de rolar seus próprios.

Finalmente, se você tiver requisitos jogo / substituição realmente complexas, você pode usar bibliotecas como StringTemplate fazer expansões modelo e substituição de jogo mais complexo.

Aqui está um exemplo de como usar a chamada 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 );

Não reinventar a roda. Eu uso StringTemplate (o C # versão) ao fazer coisas como esta.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top