4

特別な形式の特別な部分文字列を持つ文字列があります。

$(変数名)

そして、このパターンはネストされて何度も繰り返すことができます:

$(変数名$(別の変数名) )

など: [テスト文字列]

$(variableA) と $(variableB$(variableC)) を含むテスト文字列を次に示します。

このテスト文字列について、

$(変数A) = A、$(変数B) = B、$(変数C) = C、$(変数BC) = 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使用して自分自身を呼び出すことにより、置き換えたい変数の名前を構築します。トップレベルの呼び出しは、シンボルに到達しても停止しないため、エスケープせずに使用できます。stopOnClosetrue')'

ここにideoneのデモがあります。

于 2013-08-28T15:20:09.680 に答える