C # - заменить текст в середине строки и сохранить оставшуюся часть строки, дубликаты строк - PullRequest
0 голосов
/ 30 июня 2011

У меня есть два документа .txt, и я хотел бы найти в одном из них ключи из файла secoond. Если ключи найдены, я хочу заменить совпадение текстом, который следует за ключом во втором файле. Кроме того, я хотел бы добавить "T" или "B" в зависимости от числа в файле.

Вот пример первого файла:

   1       0010    SOMETEXT/NUMBERS    SOME TEXT, TEXT
   .2      0020    SOMETEXT/NUMBERS    SOME TEXT, TEXT, TEXT
   1       0020A   SOMETEXT/NUMBERS    SOME TEXT,TEXT
   .1      2000    SOMETEXT/NUMBERS    SOME TEXT,TEXT, TEXT
   ..3     9123A   SOMETEXT/NUMBERS    SOME TEXT
   ...     ...     ...                 ...

Вот пример второго файла:

  0010    ABCD EFG
  0020    C01
  0020A   C02, C3, C004, C9901, C938, C12
  2000    R123, R13, D34 
  9123A   SOMETEXT
  ...     ...

Из этих двух файлов я хотел бы использовать «ключи» из второго файла (в начале каждой новой строки). Таким образом, в этом примере ключи будут: 0010, 0020, 0020A, 2000, 9123A. После того, как у меня есть ключи, я хочу найти первый текстовый документ во втором столбце, чтобы увидеть, есть ли совпадение. Если есть совпадение (в этом случае все они совпадают), я хотел бы заменить текст в первом документе и создать новый документ с обновленным текстом. Кроме того, если после ключей во втором файле есть несколько значений, я хотел бы скопировать строки вниз. Посмотрите ниже, чтобы понять, что я имею в виду.

Новый документ будет выглядеть так:

   1       ABCD EFG   SOMETEXT/NUMBERS    SOMETEXT, TEXT
   .2      C01        SOMETEXT/NUMBERS    SOME TEXT, TEXT, TEXT
   1       C02        SOMETEXT/NUMBERS    SOME TEXT,TEXT             //--------------------
   1       C3         SOMETEXT/NUMBERS    SOME TEXT,TEXT             // Copied the lines
   1       C004       SOMETEXT/NUMBERS    SOME TEXT,TEXT             // down if there are
   1       C9901      SOMETEXT/NUMBERS    SOME TEXT,TEXT             // multiple values in
   1       C938       SOMETEXT/NUMBERS    SOME TEXT,TEXT             // document 2.
   1       C12        SOMETEXT/NUMBERS    SOMETEXT,TEXT              //--------------------
   .1      R123       SOMETEXT/NUMBERS    SOME TEXT,TEXT, TEXT       //--------------
   .1      R13        SOMETEXT/NUMBERS    SOME TEXT,TEXT, TEXT       // COPIED ALSO
   .1      D34        SOMETEXT/NUMBERS    SOME TEXT,TEXT, TEXT       //--------------
   ..3     SOMETEXT   SOMETEXT/NUMBERS    SOME TEXT
   ...     ...     ...                 ...

Кроме того, если ключ (и) оканчивается буквой "A", я хотел бы добавить букву "T" в конец приведенной выше строки. Если ключи не заканчиваются буквой «A», я бы хотел добавить букву «B» в конец приведенной выше строки.

Пример нескольких строк:

   .1      R123       SOMETEXT/NUMBERS    SOME TEXT,TEXT, TEXT         B       //key was 2000
   .1      R13        SOMETEXT/NUMBERS    SOME TEXT,TEXT, TEXT         B       //key was 2000
   .1      D34        SOMETEXT/NUMBERS    SOME TEXT,TEXT, TEXT         B       //key was 2000
   ..3     SOMETEXT   SOMETEXT/NUMBERS    SOME TEXT                    T       //key was 9123A


ВОПРОС (S):

  • Как мне искать в одном файле ключи от второго?
    • Как найти, как заменить элемент в первом тексте элементом во втором тексте?
  • После замены файла я должен заново объединить строку?
  • После того, как каждая строка правильна, есть ли «лучший» способ добавить «Т» или «В» в конце каждой строки (это зависит от того, есть ли у ключа «А» или нет)?
  • Есть еще какие-нибудь рекомендации по этому поводу?

Вот некоторый код, с которым я пытался работать ... однако я не могу получить его так, как хочу, и код работает не так, как я ожидал .:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Diagnostics;
using System.Text.RegularExpressions;
using System.Collections;

namespace BOM_Formatter
{
  public partial class bomForm : Form
  {
    // Create OpenFileDialogs to request paths and file names to open.
    OpenFileDialog openFile = new OpenFileDialog();
    OpenFileDialog openRefs = new OpenFileDialog();

    // Create a SaveFileDialog to request a path and file name to save.
    SaveFileDialog saveFile = new SaveFileDialog();

    string filePath = "C:\\Users\\FileText.txt";
    string refsPath = "C:\\Users\\RefsText.txt";

    public bomForm()
    {
        InitializeComponent();
    }

    //*********************************************************
    //******************* OPEN FILE BUTTON ********************
    //*********************************************************
    private void openButton_Click(object sender, EventArgs e)
    {
        // Initialize the OpenFileDialog to specify the .txt extension.
        openFile.DefaultExt = "*.txt";
        openFile.Filter = ".txt Files|*.txt";
        openFile.RestoreDirectory = true;

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

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

            // Calls to format the opened file.
            openFileFormatHelper();

            formattedTextRichTextBox.SaveFile(filePath, RichTextBoxStreamType.PlainText);
        }

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

    //*********************************************************
    //******************** OPEN REFS BUTTON *******************
    //*********************************************************
    private void openRefsButton_Click(object sender, EventArgs e)
    {
        // Initialize the OpenFileDialog to specify the .txt extension.
        openRefs.DefaultExt = "*.txt";
        openRefs.Filter = ".txt Files|*.txt";
        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();

            // Calls to format the opened refs file.
            openRefsFormatHelper();

            formattedRefsTextRichTextBox.SaveFile(refsPath, RichTextBoxStreamType.PlainText);
        }

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

    //*********************************************************
    //******************* SAVE FILE BUTTON ********************
    //*********************************************************
    private void saveButton_Click(object sender, EventArgs e)
    {
        // Initialize the SaveFileDialog to specify the .txt extension for the file.
        saveFile.DefaultExt = "*.txt";
        saveFile.Filter = ".txt Files|*.txt";
        saveFile.RestoreDirectory = true;

        try
        {
            // Save the contents of the formattedTextRichTextBox into the file.
            if (saveFile.ShowDialog() == DialogResult.OK && saveFile.FileName.Length > 0)
                finalTextRichTextBox.SaveFile(saveFile.FileName, RichTextBoxStreamType.PlainText);

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

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

    //*********************************************************
    //******************* CLEAR FILE BUTTON *******************
    //*********************************************************
    private void clearButton_Click(object sender, EventArgs e)
    {
        try
        {
            // Resets the text in all of the boxes.
            originalTextRichTextBox.ResetText();
            formattedTextRichTextBox.ResetText();
            refsTextRichTextBox.ResetText();
            formattedRefsTextRichTextBox.ResetText();
            finalTextRichTextBox.ResetText();
        }

        // Catches an exception if the either text box could not be cleared.
        catch (Exception)
        {
            MessageBox.Show("Could not clear the text.", "Clearing Text Box Error",
                            MessageBoxButtons.OK, MessageBoxIcon.Warning);
        }
    }

    //*********************************************************
    //******************* FORMAT FILE BUTTON ******************
    //*********************************************************
    private void formatButton_Click(object sender, EventArgs e)
    {
        try
        {
           //var list = new List<string>();
            openFileFormatHelper();
            openRefsFormatHelper();
           // formatAllHelper();

            finalFormatHelper();
        }

        // Catches an exception if the file was not opened.
        catch (Exception)
        {
            MessageBox.Show("Could not format text.", "Text Formatting Error",
                            MessageBoxButtons.OK, MessageBoxIcon.Warning);
        }
    }

    private void finalFormatHelper()
    {
        try
        {
            string[] openFileFinal = File.ReadAllLines(filePath);
            string[] openRefsFinal = File.ReadAllLines(refsPath);

            var result = new List<string>();
            string theOutput;
           // StringBuilder finalOutput = new StringBuilder();

            foreach (var fileLines in openFileFinal)
            {
                //Match numberStartMatch = Regex.Match(fileLines, @"^[\d]+");//[\s+[\d\w]+]*");
                var fileParts = fileLines.Split(' ');

                foreach (var refLines in openRefsFinal)
                {
                    var refsParts = refLines.Split(' ');
                    theOutput = fileParts.ToString();

                    if (fileParts[1].Equals(refsParts[0]))
                    {
                        theOutput = fileParts[0] + "\t" + fileParts[1].Replace(fileParts[1], refsParts[1]) 
                            + "\t" + fileParts[2] + "\t" + fileParts[3] + "\t" + fileParts[4];
                        result.Add(string.Join(" ", theOutput));
                    }
                    else
                        result.Add(theOutput);
                }
               // finalTextRichTextBox.AppendText(result.ToString());
                // Otherwise keep the line how it is.
            }
            foreach (var line in result)
            {
                finalTextRichTextBox.AppendText(line + "\n");
            }
        }

        // Catches an exception if the file could not be formatted.
        catch (Exception)
        {
            MessageBox.Show("There was a problem formatting the 'Final File'.", "Final File Format Error",
                MessageBoxButtons.OK, MessageBoxIcon.Warning);
        }
    }


    //*********************************************************
    //******************* OPEN FILE HELPER ********************
    //*********************************************************
    private void openFileFormatHelper()
    {
        try
        {
            // Resets the formattedTextRichTextBox so multiple files aren't loaded on top of eachother.
            formattedTextRichTextBox.ResetText();

            foreach (string line in File.ReadAllLines(openFile.FileName))
            {
                // Uses regular expressions to find a line that has, digit(s), space(s), digit(s) + letter(s),
                // space(s), digit(s), space(s), any character (up to 25 times).
                Match theMatch = Regex.Match(line, @"^[\.*\d]+\s+[\d\w]+\s+[\d\-\w*]+\s+.{25}");

                if (theMatch.Success)
                {
                    // Stores the matched value in string output.
                    string output = theMatch.Value;

                    // Replaces tabs and extra space with only 1 space delimiter
                    output = Regex.Replace(output, @"\s+", " ");

                    // Sets the formattedTextRichTextBox to the string output.
                    formattedTextRichTextBox.AppendText(output);
                    formattedTextRichTextBox.AppendText("\n");
                }
            }
        }

        // Catches an exception if the file was not opened.
        catch (Exception)
        {
            MessageBox.Show("There was a problem formatting the 'Open File'.", "Open File Format Error",
                            MessageBoxButtons.OK, MessageBoxIcon.Warning);
        }

        // Creates a final string of the formatted rich text box.
        //string openFileFinal = formattedTextRichTextBox.Text.ToString();
    }

    //*********************************************************
    //******************* OPEN REFS HELPER ********************
    //*********************************************************
    private void openRefsFormatHelper()
    {
        try
        {
            formattedRefsTextRichTextBox.ResetText();
            // Reads the lines in the file to format.
            var reader = File.OpenText(openRefs.FileName);

            // Creates a list for the lines to be stored in.
            var list = new List<string>();

            // Adds each line in the file to the list.
            while (true)
            {
                var line = reader.ReadLine();
                if (line == null) 
                    break;
                list.Add(line);
            }

            // Handles all of the requirements for the reference text.
            list = fourDigitRequirement(list);
            list = concatRequirement(list);
            list = startsWithBRequirement(list);
            list = elementIsBRequirement(list);
            list = removeTRequirement(list);

            // Prints the formatted refs to the richtextbox.
            foreach (var line in list)
                formattedRefsTextRichTextBox.AppendText(line + "\n");

            // Creates a final string of the formatted refs rich text box.
          //string refsFileFinal = formattedRefsTextRichTextBox.Text.ToString();
        }

        // Catches an exception if the file could not be formatted.
        catch (Exception)
        {
            MessageBox.Show("There was a problem formatting the 'Refs File'.", "Refs File Format Error",
                MessageBoxButtons.OK, MessageBoxIcon.Warning);
        }
    }

    //*********************************************************
    //****************** FORMAT ALL HELPER ********************
    //*********************************************************
   /* private void formatAllHelper()
    {
        try
        {
            finalTextRichTextBox.ResetText();

            // Reads the lines in the file to format.
            var fileReader = File.OpenText(formattedTextRichTextBox.Text);
            var refsReader = File.OpenText(formattedRefsTextRichTextBox.Text);

            // Creates a list for the lines to be stored in.
            var list = new List<string>();
            var list2 = new List<string>();

            // Adds each line in the file to the list.
            while (true)
            {
                var line = fileReader.ReadLine();
                var line2 = refsReader.ReadLine();
                if (line == null)
                    break;
                if (line2 == null)
                    break;

                list.Add(line);
                list2.Add(line2);
            }

            list = finalTextRequirement(list, list2);

            // Prints the formatted refs to the richtextbox.
            foreach (var line in list)
                finalTextRichTextBox.AppendText(line + "\n");
        }

        // Catches an exception if the file could not be formatted.
        catch (Exception)
        {
            MessageBox.Show("There was a problem formatting the 'Final Text' file.", "Final File Format Error",
                MessageBoxButtons.OK, MessageBoxIcon.Warning);
        }
    }

    public List<string> finalTextRequirement(List<string> list, List<string> list2)
    {
        // Creates variables of the text in the two rich text boxes.
        var openFileFinal = File.ReadAllLines(formattedTextRichTextBox.Text);
        var openRefsFinal = File.ReadAllLines(formattedRefsTextRichTextBox.Text);
        StringBuilder finalOutput = new StringBuilder();
        var result = new List<string>();

        try
        {
            finalTextRichTextBox.ResetText();

            // Splits the text
            var openFileFinalLines = openFileFinal.Select(f => f.Split(' ')).ToDictionary(g => g[1], h => h);
            var openRefsFinalLines = openRefsFinal.Select(f => f.Split(' ')).ToDictionary(g => g[0], h => h[1].Split(','));

            foreach (var line in openFileFinalLines)
            {
                if (openRefsFinalLines.ContainsKey(line.Key))
                    finalOutput.Append(Combine(line.Value, openRefsFinalLines[line.Key]));

                else
                    finalOutput.AppendLine(string.Join("\t", line.Value));
            }
        }

        // Catches an exception if the final output could not be created.
        catch (Exception)
        {
            MessageBox.Show("There was a problem creating the final document.", "Final Text Formatting Error",
                MessageBoxButtons.OK, MessageBoxIcon.Warning);
        }

        finalTextRichTextBox.Text = finalOutput.ToString();
        return result;
        /*
        // Creates a new list to return with new format.
        var result = new List<string>();
        var openFileFinal = File.ReadAllLines(formattedTextRichTextBox.Text);

        foreach (var line in openFileFinalLines)
        {
            if (openRefsFinalLines.ContainsKey(line.Key))
                finalOutput.Append(Combine(line.Value, openRefsFinalLines[line.Key]));

            else
                finalOutput.AppendLine(string.Join("\t", line.Value));
        }
    }

    string Combine(string[] openFileFinalLines, string[] openRefsFinalLines)
    {
        StringBuilder aBuilder = new StringBuilder();

        foreach (var theString in openRefsFinalLines)
        {
            aBuilder.AppendLine(string.Format("{0}\t{1}\t{2}\t{3}\t{4}", openFileFinalLines[0], theString, openFileFinalLines[2],
                openFileFinalLines[3], openFileFinalLines[1].EndsWith("A") ? "T" : "B"));
        }

        return aBuilder.ToString();
    }*/

    //*************************************************************
    //***************** ELEMENT IS B REQUIREMENT ******************
    //*************************************************************
    // This handles the requirement of the second element in the list being a "B".
    static List<string> elementIsBRequirement(List<string> list)
    {
        // Creates a new list to return with new format.
        var result = new List<string>();

        // Checks each line in the list.
        foreach (var line in list)
        {
            // Splits each line into 'parts'
            var parts = line.Split(' ');

            // Checks if the second 'part' array is "B"
            if (parts[1].Equals("B"))
            {
                // If it is "B", replace with "A" and add to the new list "result"
                parts[0] += "A";
                parts[1] = string.Empty;

                result.Add(string.Join(" ", parts));
            }

            // Otherwise keep the line how it is.
            else
                result.Add(line);
        }

        // Returns the new list so it can be formatted further.
        return result;
    }

    //*************************************************************
    //***************** STARTS WITH B REQUIREMENT *****************
    //*************************************************************
    // This handles the requirement of the element starting with a "B".
    static List<string> startsWithBRequirement(List<string> list)
    {
        // Creates a new list to return with new format.
        var result = new List<string>();
        var i = 0;

        // Checks if the line begins with "B"
        foreach (var line in list)
        {
            // Splits each line into 'parts'
            var parts = line.Split(' ');

            // Checks if the first 'part' array is "B"
            if (parts[0].Equals("B"))
            {
                // If it is "B", copy the previous line down and add "A" where "B" was at
                // and add to the new list "result"
                parts[0] = string.Empty;
                result.Add(list[i - 1].Split(' ')[0] + "A" + string.Join(" ", parts));
            }

            // Otherwise keep the line how it is.
            else
                result.Add(line);

            i++;
        }

        // Returns the new list so it can be formatted further.
        return result;
    }

    //*************************************************************
    //****************** CONCAT LIST REQUIREMENT ******************
    //*************************************************************
    // This handles the requirement of concatting the list.
    static List<string> concatRequirement(List<string> list)
    {
        // Creates a new list to return with new format.
        var result = new List<string>();

        // Checks each line in the list.
        foreach (var line in list)
        {
            // Splits each line into 'parts'
            var parts = line.Split(' ');
            int test;

            // Concats everything together
            if (int.TryParse(parts[0], out test) || parts[0].Equals("B"))
                result.Add(line);

            // Otherwise result - 1
            else
                result[result.Count - 1] += line;
        }

        // Returns the new list so it can be formatted further.
        return result;
    }

    //*************************************************************
    //***************** REMOVE THE T REQUIREMENT ******************
    //*************************************************************
    // This handles the requirement of removing the "T".
    static List<string> removeTRequirement(List<string> list)
    {
        // Creates a new list to return with new format.
        var result = new List<string>();

        // Checks each line in the list.
        foreach (var line in list)
        {
            // Splits each line into 'parts'
            var parts = line.Split(' ');

            // Checks if the second 'part' array is "T", if it is, remove "T"
            if (parts[1].Equals("T"))
                parts[1] = string.Empty;

            // Add the new string to the result.
            result.Add(string.Join(" ", parts).Replace("  ", " "));
        }

        // Returns the new list so it can be formatted further.
        return result;
    }

    //*************************************************************
    //****************** FOUR DIGITS REQUIREMENT ******************
    //*************************************************************
    // This handles the requirement of the digits being a certain length.
    static List<string> fourDigitRequirement(List<string> list)
    {
        // Creates a new list to return with new format.
        var result = new List<string>();

        // Checks each line in the list.
        foreach (var line in list)
        {
            // Splits each line into 'parts'
            var parts = line.Split(' ');
            int test;

            // Checks if the array[0] (digits) is the proper length.
            if (int.TryParse(parts[0], out test))
            {
                // If it is not a length of 4 digits, add "O" to the front until it is.
                parts[0] = parts[0].PadLeft(4, '0');

                // Add the new string to the result list.
                result.Add(string.Join(" ", parts));
            }

            // Otherwise keep the line how it is.
            else
                result.Add(line);
        }

        // Returns the new list so it can be formatted further.
        return result;
    }
  }
}

Сейчас мне нужно сохранить оба текстовых поля в текстовом файле, прежде чем я смогу «загрузить» их в кнопку окончательного формата, чтобы полностью отформатировать и объединить файлы. В любом случае нет необходимости сохранять файлы в виде печатной копии, а загружать их как из formattedTextRichTextBox, так и от formattedRefsRichTextBox, чтобы обрабатывать их для большего форматирования?

Ответы [ 2 ]

2 голосов
/ 30 июня 2011

Я бы прочитал в обоих файлах (возможно, используя File.ReadAllLines ()). Это даст вам массив со всеми строками в ваших файлах. Оттуда я бы использовал метод LINQ Select для проецирования линий в виде пар ключ-значение (или что-то в этом роде), возможно, преобразовал бы ToDictionary (). Затем выполните все причудливые соединения и логику в памяти и запишите их обратно в новый файл. Код ожидается (возможно)

РЕДАКТИРОВАТЬ: Я думаю, что это генерирует результат, который вы ищете.

string FileMerger()
{
    var file1 = File.ReadAllLines(@"c:\....\File1.txt");
    var file2 = File.ReadAllLines(@"c:\....\File2.txt");

    var file1Lines = file1.Select(f => f.Split('\t')).ToDictionary(f => f[1], f => f);
    var file2Lines = file2.Select(f => f.Split('\t')).ToDictionary(f => f[0], f => f[1].Split(','));

    StringBuilder newOutput = new StringBuilder();

    foreach(var line in file1Lines) 
    {
        if(file2Lines.ContainsKey(line.Key)) 
        {
            newOutput.Append(Combine(line.Value, file2Lines[line.Key]));
        }
        else 
        {
            newOutput.AppendLine(string.Join("\t", line.Value));
        }
    }

    return newOutput.ToString();
}

string Combine(string[] file1Line, string[] file2Line)
{
    StringBuilder builder = new StringBuilder();

    foreach(var str in file2Line)
    {
        builder.AppendLine(string.Format("{0}\t{1}\t{2}\t{3}\t{4}", file1Line[0], str, file1Line[2], file1Line[3], file1Line[1].EndsWith("A") ? "T" : "B"));
    }

    return builder.ToString();
}
0 голосов
/ 30 июня 2011

Вы хотите использовать библиотеку FileHelpers для чтения файлов, которые будут считывать файлы в объекты. Затем вы можете использовать Linq для объединения двух результатов и создания нового файла.

...