【问题标题】:C#: How should I convert the following?C#:我应该如何转换以下内容?
【发布时间】:2010-02-11 03:32:02
【问题描述】:

使用 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 可以包含无限深的值嵌套,也可以包含无限数量的“?=?”。

【问题讨论】:

  • 你不能用正则表达式做到这一点;您需要编写一个基于堆栈的解析器。
  • 这看起来非常类似于 JSON。与其发明一种新格式,不如直接使用它?
  • @Yuriy:我需要在控制台和/或文本文件中显示一些字符串值,而默认字符串很难确定父名称。当嵌套太深或字符串值列表太长时尤其如此。因此,需要将现有格式转换为更易于阅读的格式。

标签: c# regex string newline


【解决方案1】:

您可能想要解析它,然后生成所需的格式。尝试进行正则表达式转换不会让您有任何收获。

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

或者,在遇到每个“命名空间”时将其压入堆栈,并在遇到右大括号时将其弹出。

【讨论】:

  • 我也会走堆栈路线。
  • @Anon:如果您能提供一些堆栈方法的示例代码,将不胜感激。
  • 为此 +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();
}

【讨论】:

    【解决方案3】:

    堆栈方法的伪代码:

    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
    

    【讨论】:

      【解决方案4】:

      可以使用正则表达式来做到这一点,但这并不是最有效的方法,因为您需要多次扫描字符串。

      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
      

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-09-25
        • 1970-01-01
        • 2015-05-04
        • 2012-07-24
        • 1970-01-01
        • 2022-11-15
        • 1970-01-01
        相关资源
        最近更新 更多