3

给定以下输入和正则表达式字符串:

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

如何用我的“ReplaceToken”函数的返回值替换每个令牌(即 ${Principal}、${Rate} 和 ${Years})?

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();
}
4

3 回答 3

8

正则表达式有一个重载,它需要一个 MatchEvaluator。输入是一个匹配,它返回一个字符串。在这种情况下, Match 的值将是整个令牌,因此您可以创建一个 shim 来提取该值(您已经在 Regex 中捕获它)并适应您发布的方法。

Regex.Replace(inputString,
              tokenMatchRegexString,
              match => TokenReplacement(match.Groups[1].Value));
于 2009-12-08T20:29:08.493 回答
4

如果您真的只有少量的令牌可以替换您提前知道的,您可以使用string.Replace()来一一替换令牌。这种简单的技术可以工作,但它有缺点。它不是特别可扩展,它可能导致中间(丢弃)字符串,也可能导致代码混乱。

如果您希望有许多不同的令牌并且它们具有一致的匹配规则,您可以使用Regex.Replace()which 接受MatchEvaluator委托 - 本质上是接受正则表达式匹配并返回一个字符串以替换匹配的函数。使用Replace()带 a 的重载的好处MatchEvaluator是它有助于避免创建中间字符串,然后这些字符串仅用于替换下一个匹配项。重用内置的 .NET 类而不是滚动你自己的类也很好。

最后,如果您有非常复杂的匹配/替换要求,您可以使用StringTemplate 之类的库来进行更复杂的模板扩展和匹配替换。

下面是一个使用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 );
于 2009-12-08T20:32:56.320 回答
0

不要重新发明轮子。我在做这样的事情时使用StringTemplate (C# 版本)。

于 2009-12-08T20:22:56.443 回答