4

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

$(变量名)

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

$(变量名$(另一个变量名) )

如:[一个测试字符串]

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

对于这个测试字符串假设

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

我想要的是用实际值替换那些特殊模式 -> $(variableName),例如结果字符串应该是:

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

对通用和优雅的解决方案有什么建议吗?

4

1 回答 1

3

这是一个执行递归下降解析的简单解决方案:

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。顶级调用不会在到达')'符号时停止,让您可以不转义地使用它。

这是ideone的演示。

于 2013-08-28T15:20:09.680 回答