1

我的应用程序应该读取一个未缩进的C# 代码示例,然后以编程方式缩进代码。我这样做的方式可能不正确,但仍然可以取得部分结果。

我可以在找到 a 时设置空格,{然后继续使用相同数量的空间来读取其余行。当再次{找到另一个时,添加空格并继续使用这个新的空间作为其余行。为此,这就是我所做的:

    private void btn_format_Click(object sender, EventArgs e)
    {
        string lineInfo = "";
        string fl = "";
        string ctab= char.ConvertFromUtf32(32)+char.ConvertFromUtf32(32)+char.ConvertFromUtf32(32);
        foreach (string line in txt_codepage.Lines) // text_codepage is a textbox with code
        {
            if (line.Contains("{"))
            {
                string l = line.Replace("{", ctab+"{");
                lineInfo = lineInfo + (l + "\n");
                fl = fl + ctab;
                ctab = ctab + ctab;
            }
            else
            {
                lineInfo = lineInfo + (char.ConvertFromUtf32(32)+fl+ line + "\n");
            }

我可以达到我想要的正确缩进到这里。现在,当我找到一个}我应该做相反的过程但不幸的是,这是不可能的字符串。我的意思的相反过程是这样的:

            if (line.Contains("}"))
            {
                string l = line.Replace(ctab + "}", "}");
                lineInfo = lineInfo + (l + "\n");
                fl = fl - ctab;
                ctab = ctab - ctab;
            }
            else
            {
                lineInfo = lineInfo - (char.ConvertFromUtf32(32) + fl + line + "\n");

            }
        }
        MessageBox.Show(lineInfo.ToString());

我知道代码的上述部分是一个完整的错误,但让我知道如何以正确的方式实现它

4

3 回答 3

2

如果要解析字符串,则应使用 StringBuilder 代替字符串连接(连接会变慢)。我写了一些代码,来演示如何解析 CS 或其他代码。这不是一个完整的例子,只是一个基本概念。

如果您想了解有关解析器的更多信息,可以阅读编译器:原理、技术和工具

public static string IndentCSharpCode(string code)
{
    const string INDENT_STEP = "    ";

    if (string.IsNullOrWhiteSpace(code))
    {
        return code;
    }

    var result = new StringBuilder();
    var indent = string.Empty;
    var lineContent = false;
    var stringDefinition = false;

    for (var i = 0; i < code.Length; i++)
    {
        var ch = code[i];

        if (ch == '"' && !stringDefinition)
        {
            result.Append(ch);
            stringDefinition = true;
            continue;
        }

        if (ch == '"' && stringDefinition)
        {
            result.Append(ch);
            stringDefinition = false;
            continue;
        }

        if (stringDefinition)
        {
            result.Append(ch);
            continue;
        }

        if (ch == '{' && !stringDefinition)
        {
            if (lineContent)
            {
                result.AppendLine();
            }

            result.Append(indent).Append("{");

            if (lineContent)
            {
                result.AppendLine();
            }

            indent += INDENT_STEP;
            lineContent = false;

            continue;
        }

        if (ch == '}' && !stringDefinition)
        {
            if (indent.Length != 0)
            {
                indent = indent.Substring(0, indent.Length - INDENT_STEP.Length);
            }

            if (lineContent)
            {
                result.AppendLine();
            }

            result.Append(indent).Append("}");

            if (lineContent)
            {
                result.AppendLine();
            }


            lineContent = false;

            continue;
        }

        if (ch == '\r')
        {
            continue;
        }

        if ((ch == ' ' || ch == '\t') && !lineContent)
        {
            continue;
        }

        if (ch == '\n')
        {
            lineContent = false;
            result.AppendLine();

            continue;
        }

        if (!lineContent)
        {
            result.Append(indent);
            lineContent = true;
        }

        result.Append(ch);
    }

    return result.ToString();
}
于 2012-08-12T15:16:10.183 回答
1

你可以去看看codemaid,一个用于清理代码的开源 VS 插件

于 2012-08-12T14:57:37.963 回答
0

使用 String.Trim() 从行中删除所有空格,然后仅添加所需的选项卡。此外,如果您可以避免使用 char.ConvertFromUtf32(32),您的代码将更具可读性 - 为什么要写它而不是 " " 或 ' '?

于 2012-08-12T14:41:58.910 回答