Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# - Read/Copy/Replace Lines In Text

I have a text file that I am opening up and it is in a similar format to this:

  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

With this text I need to be able to read it and replace values accordingly. If a ReadLine begins with a number (ie, 10, 20, 30, 40, 60, 100, 360, 2000, 423) I need to to check if there is a T, B, or text after it. The only case that I need to change/reformat the lines when they come in and output them differently.

Example: 10 is fine except for I would like to add zeros in front of every number to make them 4 digits long (ie, 10 turns to 0010, 360 turns to 0360, 2000 stays the same). When the string "B B5, C45, D48" is read (this is the third line in the text) I need to change it to say "20A B5, C45, D48". I need to grab the number above the "B" and concat it to the "B" and replace the "B" with an "A". If instead of a "B" there is a "T" I simply need to remove the "T". Also, if a line does not start with a number or a "B" (ie, Q31 or W37) I need to concat that line with the previous line.


So after the changes take place it should look like this:

  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

I am currently trying to use Regex to do this but I have been told that there is an easier way to do this and I am not sure how. So far I have been able to add the zeros in front of the numbers. Also, my code is adding an "A" to the end of everything as well as keeping the original number on the next line and I am not grabbing the lines that begin with anything but a digit.

This is what my current output is turning out to look like:

    0010A 
    0010
    0020A 
    0020

    0030A 
    0030
    0060A 
    0060



    0100A 
    0100
    0360A 
    0360
    2000
    2000
    0423A 
    0423

I am obviously doing something wrong using Regex.

Here is my current code:

    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);
        }
    }
}

}

QUESTION(S):

  • What is a better way to go about doing this task?
  • Are there any recommendations on changing my code to be more efficient and cleaner?
  • How do I properly split each line into number, T/B, A40 when every line is not the same?
  • After the lines are properly split, how do I replace copy the line before if the current line begins with a "B"?
    • If the line begins with "Q31" or similar, how do I add that current line to the end of the previous one?
  • Once this happens, is there a way to concat everything to create the speficied format above?

WORK FLOW @jaywayco

  • Open Text File
  • Read file line by line
    • Save each line in a list of strings
  • Split each string by ' '
  • Find each line that starts with a digit
    • Replace that digit to make it 4 digits in length
    • Check the following text after the digit to see if it is a "B ", "T ", or "SOME TEXT"
      • if "B " copy the line above
        • Add an "A" to the end of the digit
      • if "T " remove the "T "
      • if "SOME TEXT" do nothing
  • Find each line that starts with a "B "
    • Copy the digits on the line above and concat to the front of the "B "
      • Follow step 4.b.i
  • Find each line that starts with (or similar to) "Q31"
    • Concat this line to the end of the previous line
  • ...?
like image 926
theNoobGuy Avatar asked Aug 20 '26 02:08

theNoobGuy


1 Answers

Here's a really lame, procedural solution:

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;
        }
    }
}
like image 134
Dave Ziegler Avatar answered Aug 21 '26 17:08

Dave Ziegler



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!