字符串替换为递归字典值

时间:2016-11-01 20:04:58

标签: c# dictionary recursion

我在app.config文件中配置了所有根api url,该文件被加载到键和值对的字典中。

<endpoint name="saveuser" address="[clientRefUrl]/SaveUser" />

我有一个来自配置文件的api url,如https://company.com/api/RealtimeReferenceData/SaveUser

我想在c#代码中将该网址构建为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";

但是,当我不得不评估一个字符串时,递归并不顺利: {{1}}继续尝试评估不属于字典的其他变量。

2 个答案:

答案 0 :(得分: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将永远不会结束。添加必要的检查或限制重复次数。

答案 1 :(得分: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;
}