3

次の入力文字列と正規表現文字列があるとします。

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

各トークン(つまり、$ {Principal}、$ {Rate}、および$ {Years})を「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();
}
4

3 に答える 3

8

正規表現には、MatchEvaluatorを使用するオーバーロードがあります。入力はMatchであり、文字列を返します。この場合のMatchの値はトークン全体になるため、値を抽出し(Regex内で既にキャプチャしている)、投稿したメソッドに適応するシムを作成できます。

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

事前に知っている少数のトークンを置き換える必要がある場合は、 を使用string.Replace()してトークンを 1 つずつ置き換えることができます。この単純な手法は機能しますが、欠点もあります。これは特に拡張可能ではなく、中間 (使い捨て) 文字列になる可能性があり、コードが混乱する可能性もあります。

多くの異なるトークンが予想され、一致する規則が一貫している場合Regex.Replace()は、デリゲートを取る which を使用できます。これは、MatchEvaluator基本的に、正規表現の一致を受け入れ、一致を置き換える文字列を返す関数です。Replace()を受け取るオーバーロードを使用する利点は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 に答える