C# - 读取/复制/替换文本中的行

标签 c# string replace copy line

我有一个正在打开的文本文件,它的格式与此类似:

  10 SOME TEXT
  20 T A40
  B B5, C45, D48
  30 B E25
  40 B F17, G18
  60 T H20, I23,
  B J6, K7, L8, M9, N10, O11, P12,
  Q31, R32, S33, T34, U35, V36,
  W37, X38, Y39
  100 T Z65
  360 B A1, B4, C5, D6, E7, F10
  2000 T SOME TEXT
  423 TEXT

有了这个文本,我需要能够阅读它并相应地替换值。如果 ReadLine 以数字开头(即 10、20、30、40、60、100、360、2000、423),我需要检查它后面是否有 T、B 或文本。唯一需要在输入行时更改/重新格式化行并以不同方式输出的情况。

示例:10 很好,除了我想在每个数字前添加零,使它们的长度为 4 位(即,10 变为 0010,360 变为 0360,2000 保持不变)。当读取字符串“B B5, C45, D48”时(这是文本中的第三行),我需要将其更改为“20A B5, C45, D48”。我需要获取“B”上方的数字并将其连接到“B”并将“B”替换为“A”。如果不是“B”而是“T”,我只需要删除“T”。此外,如果一行不是以数字或“B”(即 Q31 或 W37)开头,我需要将该行与上一行连接起来。


所以在更改发生后它应该看起来像这样:

  0010 SOME TEXT
  0020 A40
  0020A B5, C45, D48
  0030A E25
  0040A F17, G18
  0060 H20, I23,
  0060A J6, K7, L8, M9, N10, O11, P12, Q31, R32, S33, T34, U35, V36, W37, X38, Y39
  0100 Z65
  0360A A1, B4, C5, D6, E7, F10
  2000 SOME TEXT
  0423 TEXT

我目前正在尝试使用 Regex 来执行此操作,但有人告诉我有一种更简单的方法来执行此操作,但我不确定如何操作。到目前为止,我已经能够在数字前添加零。此外,我的代码在所有内容的末尾添加了一个“A”,并在下一行保留了原始数字,并且我没有抓取以数字以外的任何内容开头的行。

这就是我当前的输出结果:

    0010A 
    0010
    0020A 
    0020

    0030A 
    0030
    0060A 
    0060



    0100A 
    0100
    0360A 
    0360
    2000
    2000
    0423A 
    0423

我显然在使用 Regex 时做错了。

这是我当前的代码:

    private void openRefsButton_Click(object sender, EventArgs e)
    {
        // Initialize the OpenFileDialog to specify the .txt extension as well as
        // its intial directory for the file.
        openRefs.DefaultExt = "*.txt";
        openRefs.Filter = ".txt Files|*.txt";
        openRefs.InitialDirectory = "C:\\";
        openRefs.RestoreDirectory = true;

        try
        {
            // Open the contents of the file into the originalTextRichTextBox.
            if (openRefs.ShowDialog() == DialogResult.OK && openRefs.FileName.Length > 0)
                refsTextRichTextBox.LoadFile(openRefs.FileName, RichTextBoxStreamType.PlainText);

            // Throws a FileNotFoundException otherwise.
            else
                throw new FileNotFoundException();

            StreamReader refsInput = File.OpenText(openRefs.FileName);

            string regExpression = @"^[\d]+";
            string findNewBottomRegex = @"^B\s";

            StringBuilder buildNumberText = new StringBuilder();
            StringBuilder formatMatchText = new StringBuilder();

            foreach (string allLines in File.ReadAllLines(openRefs.FileName))
            {
                Match newBottomMatch = Regex.Match(allLines, findNewBottomRegex);
                Match numberStartMatch = Regex.Match(allLines, regExpression);
                int counter = 0;

                if (counter < numberStartMatch.Length)
                {
                    if (numberStartMatch.Value.Length == 2)
                    {
                        if (refsTextRichTextBox.Text.Contains(newBottomMatch.ToString()))
                        {
                            finalTextRichTextBox.AppendText("00" + numberStartMatch + "A\n");
                        }

                        finalTextRichTextBox.AppendText("00" + numberStartMatch + "\n");
                    }

                    else if (numberStartMatch.Value.Length == 3)
                    {
                        if (refsTextRichTextBox.Text.Contains(newBottomMatch.ToString()))
                        {
                            finalTextRichTextBox.AppendText("0" + numberStartMatch + "A\n");
                        }

                        finalTextRichTextBox.AppendText("0" + numberStartMatch + "\n");
                    }

                    else
                    {
                        if (refsTextRichTextBox.Text.Contains(newBottomMatch.ToString()))
                        {
                            finalTextRichTextBox.AppendText(numberStartMatch + "A\n");
                        }

                        finalTextRichTextBox.AppendText(numberStartMatch + "\n");
                    }
                    counter++;
                }
            }
        }

        // Catches an exception if the file was not opened.
        catch (Exception)
        {
            MessageBox.Show("There was not a specified file path.", "Path Not Found Error",
                            MessageBoxButtons.OK, MessageBoxIcon.Warning);
        }
    }
}

问题(S):

  • 执行此任务的更好方法是什么?
  • 是否有关于更改我的代码以使其更高效、更简洁的建议?
  • 当每行不相同时,如何将每行正确拆分为数字、T/B、A40?
  • 正确拆分行后,如果当前行以“B”开头,如何替换复制之前的行?
    • 如果该行以“Q31”或类似内容开头,我该如何将当前行添加到上一行的末尾?
  • 一旦发生这种情况,是否有办法连接所有内容以创建上面指定的格式?

工作流程@jaywayco

  • 打开文本文件
  • 逐行读取文件
    • 将每一行保存在一个字符串列表中
  • 用' '分割每个字符串
  • 查找以数字开头的每一行
    • 替换该数字使其长度为 4 位数字
    • 检查数字后面的文本,看它是“B”、“T”还是“SOME TEXT”
      • 如果“B”复制上面的行
        • 在数字末尾添加一个“A”
      • 如果“T”去掉“T”
      • 如果“SOME TEXT”什么都不做
  • 找到以“B”开头的每一行
    • 复制上面一行的数字并连接到“B”的前面
      • 执行步骤 4.b.i
  • 找到以“Q31”开头(或类似)的每一行
    • 将这一行连接到上一行的末尾
  • ...?

最佳答案

这是一个非常蹩脚的程序解决方案:

using System.IO;
using System.Collections.Generic;

namespace ConsoleApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            var list = new List<string>();

            using (var reader = File.OpenText(@"c:\input.txt"))
            {
                while (true)
                {
                    var line = reader.ReadLine();
                    if (string.IsNullOrEmpty(line)) break;
                    list.Add(line);
                }
            }

            list = HandleRemoveTRequirement(list);
            list = HandleFourDigitRequirement(list);
            list = HandleConcatRequirement(list);
            list = HandleStartsWithBRequirement(list);
            list = HandleSecondElementIsBRequirement(list);

            using (var output = new StreamWriter(@"c:\output.txt"))
            {
                foreach (var line in list)
                {
                    output.WriteLine(line);
                }
            }
        }

        static List<string> HandleSecondElementIsBRequirement(List<string> list)
        {
            var result = new List<string>();

            foreach (var line in list)
            {
                var parts = line.Split(' ');

                if (parts[1].Equals("B"))
                {
                    parts[0] += "A";
                    parts[1] = string.Empty;
                    result.Add(string.Join(" ", parts).Replace("  ", " "));
                }
                else
                {
                    result.Add(line);
                }
            }

            return result;
        }

        static List<string> HandleStartsWithBRequirement(List<string> list)
        {
            var result = new List<string>();
            var i = 0;

            foreach (var line in list)
            {
                var parts = line.Split(' ');

                if (parts[0].Equals("B"))
                {
                    parts[0] = string.Empty;
                    result.Add(list[i - 1].Split(' ')[0] + "A" + string.Join(" ", parts));
                }
                else
                {
                    result.Add(line);
                }

                i++;
            }

            return result;
        }

        static List<string> HandleConcatRequirement(List<string> list)
        {
            var result = new List<string>();

            foreach (var line in list)
            {
                var parts = line.Split(' ');
                int test;
                if (int.TryParse(parts[0], out test) || parts[0].Equals("B"))
                {
                    result.Add(line);
                }
                else
                {
                    result[result.Count -1] += line;
                }
            }

            return result;
        }

        static List<string> HandleRemoveTRequirement(List<string> list)
        {
            var result = new List<string>();

            foreach (var line in list)
            {
                var parts = line.Split(' ');
                if (parts[1].Equals("T"))
                {
                    parts[1] = string.Empty;
                }
                result.Add(string.Join(" ", parts).Replace("  ", " "));
            }

            return result;
        }

        static List<string> HandleFourDigitRequirement(List<string> list)
        {
            var result = new List<string>();

            foreach (var line in list)
            {
                var parts = line.Split(' ');
                int test;
                if (int.TryParse(parts[0], out test))
                {
                    parts[0] = parts[0].PadLeft(4, '0');
                    result.Add(string.Join(" ", parts));
                }
                else
                {
                    result.Add(line);
                }
            }

            return result;
        }
    }
}

关于C# - 读取/复制/替换文本中的行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6524438/

相关文章:

c# - 如何在 wpf 中自动将高度设置为 itemscontrol?

c# - 如何通过正则表达式检查允许 '[' 和 ']'

Python - 比较文件中的字符串

variables - 在 sed 命令中使用变量而不是值来替换文本文件中的单词

c++ - 从双引号包围的子字符串中删除特定字符

javascript - 替换 - 用 - 使用 replace()

c# - 属性类型不是 DBContext 中的有效键类型

c# - 根据模型验证 ASP.NET MVC2 FormCollection

c# - 查看 Excel 是否处于 .NET 中的单元格编辑模式的解决方法

php - 如何删除字符串中的所有前导零