2016-11-01 24 views
0

キーと値のペアの辞書に読み込まれるapp.configファイル内のすべてのルートapi URLを設定しています。文字列を再帰ディクショナリ値に置き換えます。

Dictionary<string, string> variables = new Dictionary<string, string>() 
    { 
     { "clientRefUrl", "[clientBaseUrl]/RealtimeReferenceData"},  
     { "clientRealtimeUrl", "[clientBaseUrl]/RealtimeClinicalData"}, 
     { "localApiUrl", "LocalApi/Generic"}, 
     { "integrationRootFolder", "C:\\LocalServer\\Integration"}, 
     { "clientBaseUrl", "https://company.com/api"}, 
     { "clientAuthBaseUrl", "https://auth.company.com/api"} 
    }; 

私は<endpoint name="saveuser" address="[clientRefUrl]/SaveUser" />のような設定ファイルから来ているAPIのURLを持っています。

私はそのURLをC#コードでhttps://company.com/api/RealtimeReferenceData/SaveUserとしたいと考えています。

私は以下の方法でこれを行うことができますが、クライアントはclientBaseUrlをリストの先頭に移動しないようにしなければならないという問題があります。または、リストの先頭への依存キー。

public static string EvaluateStringWithVariables(string strExpr) 
{ 
    Dictionary<string, string> variables = new Dictionary<string, string>() 
    { 
     { "clientRefUrl", "[clientBaseUrl]/RealtimeReferenceData"},  
     { "clientRealtimeUrl", "[clientBaseUrl]/RealtimeClinicalData"}, 
     { "localApiUrl", "LocalApi/Generic"}, 
     { "integrationRootFolder", "C:\\LocalServer\\Integration"}, 
     { "clientBaseUrl", "https://company.com/api"}, 
     { "clientAuthBaseUrl", "https://auth.company.com/api"} 
    }; 

    foreach (string variable in variables.Keys) 
    { 
     var pattern = @"\[" + variable + @"\]"; 
     strExpr = Regex.Replace(strExpr, pattern, variables[variable]); 
    } 

    return strExpr; 
} 

制限なく同じ方法を実行するより良い方法がありますか?私は正規表現と再帰を使用する別の解決策を試してみました:

public static string EvaluateStringWithVariables(string strExpr) 
{ 
    Dictionary<string, string> variables = new Dictionary<string, string>() 
    { 
     { "clientRefUrl", "[clientBaseUrl]/RealtimeReferenceData"},  
     { "clientRealtimeUrl", "[clientBaseUrl]/RealtimeClinicalData"}, 
     { "localApiUrl", "LocalApi/Generic"}, 
     { "integrationRootFolder", "C:\\LocalServer\\Integration"}, 
     { "clientBaseUrl", "https://company.com/api"}, 
     { "clientAuthBaseUrl", "https://auth.company.com/api"} 
    }; 

    Regex regEx = new Regex(@"\[(\w+)\]", RegexOptions.Compiled); 

    strExpr = regEx.Replace(strExpr, match => 
    { 
     string val = String.Empty; 
     if (variables.TryGetValue(match.Groups[1].Value, out val)) 
     { 
      return val; 
     } 
     return match.Value; 
    }); 

    Match rmatch = regEx.Match(strExpr); 
    if (rmatch.Success) 
    { 
     return EvaluateStringWithVariables(strExpr); 
    } 

    return strExpr; 
} 

しかし、私はのような文字列を評価するために持っていたとき、再帰はうまくいきませんでした:辞書の一部ではない他の変数を評価しようとし続ける strExpr = "[integrationRootFolder]\\myfolder\\[msg.ClientId]\\In\\[personid]_[tabid]_[documentname]_[msg.ClientId].pdf";を。

+3

ディクショナリが注文されていない場合、あなたのユーザーが注文をリセットしなくても、あなたの 'foreach'が注文を維持するとは思わないはずです。また、私はあなたが正規表現の解決策でどのような問題を抱えているのかは分かりません。もちろん、辞書にないものをテストするつもりです。辞書の全体はテストが速いということです。プログラムを実行するまでは一致を維持するだけで、 'variables.TryGetValue'は決してtrueを返しません。 –

+0

はい@ScottChamberlain、これは別の問題です。それを指してくれてありがとう。 –

答えて

0

あなたの正規表現の解はかなり近いと思います。置換したときに辞書内の値が見つかったかどうか、そして再帰的に呼び出すかどうかを確認するだけです。

public static string EvaluateStringWithVariables(string strExpr) 
{ 
    Dictionary<string, string> variables = new Dictionary<string, string>() 
    { 
     { "clientRefUrl", "[clientBaseUrl]/RealtimeReferenceData"},  
     { "clientRealtimeUrl", "[clientBaseUrl]/RealtimeClinicalData"}, 
     { "localApiUrl", "LocalApi/Generic"}, 
     { "integrationRootFolder", "C:\\LocalServer\\Integration"}, 
     { "clientBaseUrl", "https://company.com/api"}, 
     { "clientAuthBaseUrl", "https://auth.company.com/api"} 
    }; 

    Regex regEx = new Regex(@"\[(\w+)\]", RegexOptions.Compiled); 

    bool foundMatch = false; 
    strExpr = regEx.Replace(strExpr, match => 
    { 
     string val = String.Empty; 
     if (variables.TryGetValue(match.Groups[1].Value, out val)) 
     { 
      foundMatch = true; 
      return val; 
     } 
     return match.Value; 
    }); 

    Match rmatch = regEx.Match(strExpr); 
    if (rmatch.Success && foundMatch) 
    { 
     return EvaluateStringWithVariables(strExpr); 
    } 

    return strExpr; 
} 
0

あなたの最初のアプローチには、迅速ではあるが最適ではない解決策/修正があります。

string prev; 
do { 
prev = strExpr; 
foreach (string variable in variables.Keys) 
    { 
     var pattern = @"\[" + variable + @"\]"; 
     strExpr = Regex.Replace(strExpr, pattern, variables[variable]); 
    } 
} 
until (prev == strExpr); 

文字列に置換文字がなくなるまで、置換が繰り返されます。 置換定義で可能なループに注意する必要があります。もしあれば、do-loopは決して終わらないでしょう。必要なチェックを追加するか、繰り返し回数を制限する。

関連する問題