在C#中评估特殊表达式

时间:2013-08-28 14:53:17

标签: c# parsing string-parsing

我的字符串有一个特殊格式的特殊子字符串:

  

$( variableName

这种模式可以多次重复嵌套:

$( variableName $( anotherVariableName ))

如:[测试字符串]

  

这是一个包含$(variableA)和的测试字符串   $(variableB的$(variableC))

对于此测试字符串,我们假设

  

$(variableA)= A,$(variableB)= B,$(variableC)= C,$(variableBC)= Y

我想要的是替换那些特殊的图案 - > $(variableName)具有实际值,例如 结果字符串应为:

  

这是一个包含A和Y的测试字符串

对通用优雅解决方案的任何建议?

1 个答案:

答案 0 :(得分:3)

以下是执行recursive descent parsing的简单解决方案:

public static string Replace(
    string input
,   ref int pos
,   IDictionary<string,string> vars
,   bool stopOnClose = false
) {
    var res = new StringBuilder();
    while (pos != input.Length) {
        switch (input[pos]) {
            case '\\':
                pos++;
                if (pos != input.Length) {
                    res.Append(input[pos++]);
                }
                break;
            case ')':
                if (stopOnClose) {
                    return res.ToString();
                }
                res.Append(')');
                pos++;
                break;
            case '$':
                pos++;
                if (pos != input.Length && input[pos] == '(') {
                    pos++;
                    var name = Replace(input, ref pos, vars, true);
                    string replacement;
                    if (vars.TryGetValue(name, out replacement)) {
                        res.Append(replacement);
                    } else {
                        res.Append("<UNKNOWN:");
                        res.Append(name);
                        res.Append(">");
                    }
                    pos++;
                } else {
                    res.Append('$');
                }
                break;
            default:
                res.Append(input[pos++]);
                break;
        }
    }
    return res.ToString();
}
public static void Main() {
    const string input = "Here is a test string contain $(variableA) and $(variableB$(variableC))";
    var vars = new Dictionary<string, string> {
        {"variableA", "A"}, {"variableB", "B"}, {"variableC", "C"}, {"variableBC", "Y"}
    };
    int pos = 0;
    Console.WriteLine(Replace(input, ref pos, vars));
}

此解决方案重用Replace的实现,通过将stopOnClose标志设置为true来调用自身来构建要替换的变量的名称。顶级调用不会在到达')'符号时停止,让您可以使用未转义符号。

Here is a demo on ideone.