C#:我应该如何转换以下内容?

时间:2010-02-11 03:32:02

标签: c# regex string newline

使用C#,您将如何转换String,其中还包含以下格式的换行符和制表符(4个空格)

A {
   B {
      C = D
      E = F
   }
   G = H
}

进入以下

A.B.C = D
A.B.E = F
A.G = H

请注意,A到H只是String值的占位符,不包含“{”,“}”和“=”字符。上面只是一个例子,转换的实际String可以包含无限深的值嵌套,也可以包含无限数量的“?=?”。

4 个答案:

答案 0 :(得分:6)

您可能想要解析它,然后生成所需的格式。尝试进行正则表达式转换不会让你随处可见。

对字符串进行标记,然后遍历标记并构建语法树。然后走树生成输出。

替代方案,在遇到它时将每个“命名空间”推入堆栈,并在遇到闭括号时将其弹出。

答案 1 :(得分:2)

不是很漂亮,但这是一个使用堆栈的实现:

static string Rewrite(string input)
{
    var builder = new StringBuilder();
    var stack = new Stack<string>();
    string[] lines = input.Split('\n');
    foreach (var s in lines)
    {
        if (s.Contains("{") || s.Contains("="))
        {
            stack.Push(s.Replace("{", String.Empty).Trim());
        }
        if (s.Contains("="))
        {
            builder.Append(string.Join(".", stack.Reverse().ToArray()));
            builder.Append(Environment.NewLine);
        }
        if (s.Contains("}") || s.Contains("="))
        {
            stack.Pop();
        }
   }
   return builder.ToString();
}

答案 2 :(得分:1)

堆栈方法的伪代码:

function do_processing(Stack stack)
    add this namespace to the stack;
    for each sub namespace of the current namespace
        do_processing(sub namespace)
    end
    for each variable declaration in the current namespace
        make_variable_declaration(stack, variable declaration)
    end
end

答案 3 :(得分:1)

可以使用正则表达式执行此操作,这不是最有效的方法,因为您需要多次扫描字符串。

while (s.Contains("{")) {
    s = Regex.Replace(s, @"([^\s{}]+)\s*\{([^{}]+)\}", match => {
        return Regex.Replace(match.Groups[2].Value,
                             @"\s*(.*\n)",
                             match.Groups[1].Value + ".$1");
    });
}

结果:

A.B.C = D
A.B.E = F
A.G = H

我仍然认为使用解析器和/或基于堆栈的方法是最好的方法,但我只是想提供一种替代方法。