C#Regex:如何使用在运行时生成的字符串替换标记?

时间:2009-12-08 20:17:42

标签: regex c#-3.0 token capture-group

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

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

3 个答案:

答案 0 :(得分:7)

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

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

答案 1 :(得分:2)

如果您真的只需要少量代币来替换您提前知道的代币,则可以使用string.Replace()逐个替换代币。这种简单的技术可以工作,但它有缺点。它不是特别可扩展的,它可能导致中间(一次性)字符串,并且还可能导致令人困惑的代码。

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

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

以下是使用MatchEvaluator调用的示例:

Regex.Replace()

答案 2 :(得分:0)

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