Поиск и замена строкового шаблона в C# - PullRequest
0 голосов
/ 10 июля 2020

У меня есть ситуация, когда в текстовом файле много строк, как показано ниже. Мне нужно найти этот шаблон и заменить коды источника и столбца значениями. Как мы можем найти этот шаблон строки и заменить его в c#, пожалуйста? Спасибо.

фактический текст: "anytext [ Source1 ]. [Anytext: Column1 : anytext] anytext"

обновленный текст: "anytext [ AB C]. [Anytext: Col1 : anytext] anytext "

Комбинации кода и значений выглядят так, как показано ниже.

SourceCode ColumnCode Sourcevalue ColumnValue

====== ======== ========== ==========

Source1 Column1 AB C Column1

Source2 Column2 DEF Column2

Source3 Column3 GHI Col3

Ответы [ 4 ]

1 голос
/ 10 июля 2020

Я использовал два отдельных словаря, чтобы связать поля источника и столбца, так как я думал, что связи только между полями источника и столбца. Пример кода предназначен для кнопки, которая заменяет текст метки при нажатии, но его можно адаптировать к любой подобной ситуации. Пока это то, что я придумал:

using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Forms;

namespace RegexTest
{

public partial class Form1 : Form
{
    Dictionary<string, string> values = new Dictionary<string, string>();
    Dictionary<string, string> columns = new Dictionary<string, string>();
    public Form1()
    {
        InitializeComponent();
        InitValues();
    }

    private void InitValues()
    {
        values.Add("Source1", "ABC");
        values.Add("Source2", "DEF");
        values.Add("Source3", "GHI");

        columns.Add("Column1", "Col1");
        columns.Add("Column2", "Col2");
        columns.Add("Column3", "Col3");
    }

    private void button1_Click(object sender, EventArgs e)
    {

        // Create the pattern
        string pattern = "[a-z1-9]+\\[Source[0-9]+\\]\\.\\[[a-z1-9]+:Column[0-9]+:[a-z1-9]+\\][a-z1-9]+";
        // Create a Regex  
        Regex rg = new Regex(pattern);
        // Get all matches  
        MatchCollection matchedValues = rg.Matches(label1.Text);

        StringBuilder sb = new StringBuilder();
        // Replace all matches 
        for (int count = 0; count < matchedValues.Count; count++)
        {          
            //copy the anytext part until the source
            sb.Append(matchedValues[count].Value.Substring(0, matchedValues[count].Value.IndexOf('[')));
            //replace the Source parts
            sb.Append(values[matchedValues[count].Value.Substring(matchedValues[count].Value.IndexOf('[') + 1,
                matchedValues[count].Value.IndexOf(']') - matchedValues[count].Value.IndexOf('['))]);
            //now copy in the same way the anytext after source
            //split in the same way around the : and use the columns dictionary

            //finally, replace the original string with the value from string builder
            label1.Text = sb.ToString();
            sb.Clear();
        }
    }
}
}

Остальные части выполнены аналогичным образом (я только заставил его найти первую часть, «источник», для части столбца это тем же). Если вам понадобится дополнительная помощь, спросите, и я отвечу как можно скорее. Я также предположил, что части anytext могут содержать только буквенно-цифровой текст, если там можно найти другие символы, я отредактирую шаблон регулярного выражения.

0 голосов
/ 10 июля 2020

Просто опубликовал окончательный код, который я получил, работая с подходом, предложенным @ Youssef13

Dictionary<Tuple<string, string>,Tuple<string,string>> sourcecolumncodeandvalue = new Dictionary<Tuple<string, string>, Tuple<string, string>>();
            sourcecolumncodeandvalue.Add(Tuple.Create("Source1", "Column1"), Tuple.Create("ABC", "Col1"));
            sourcecolumncodeandvalue.Add(Tuple.Create("Source2", "Column2"), Tuple.Create("DEF", "Col2"));

            Dictionary<string, string> codeandvaluereplacementlist = new Dictionary<string, string>();

            var pattern = @"\[(.*?)\]\.\[(.*?)\]";
            var filetext = "anytext[Source1].[anytext:Column1:anytext]anytext anytext[Source2].[anytext:Column2:anytext]anytext";
            var matchesfound = System.Text.RegularExpressions.Regex.Matches(filetext, pattern); //find the pattern [].[]
            foreach (System.Text.RegularExpressions.Match  m in matchesfound)
            {
                string datasource = string.Empty;
                string columnname = string.Empty;
                string replacementtext = string.Empty;

                string[] sourceandcolumnsplit = m.Value.ToString().Split('.');//split [].[] into two based on '.' character
                datasource = sourceandcolumnsplit[0].Replace("[","").Replace("]",""); //remove square brackets               
                //Column value is in between ':' character (ex: anytext:Column2:anytext)  so split it further 
                string[] columnsplit = sourceandcolumnsplit[1].Split(':');
                columnname = columnsplit[1];
                //We got the source and column codes, now get corresponding values from the dictionary
                Tuple<string,string> sourceandcolumnvalues;
                sourcecolumncodeandvalue.TryGetValue(Tuple.Create(datasource, columnname),out sourceandcolumnvalues);

                //construct the replacement value string for each code string
                codeandvaluereplacementlist.Add(m.Value.ToString(), "[" + sourceandcolumnvalues.Item1 + "]." + columnsplit[0] + ":" + sourceandcolumnvalues.Item2 + ":" + columnsplit[2]);
            }
            //Finally loop through all code matches and replace with values in the file text
            foreach (var codeandvalue in codeandvaluereplacementlist)
            {
                filetext = filetext.Replace(codeandvalue.Key, codeandvalue.Value);
            }
0 голосов
/ 10 июля 2020

Я бы не стал предоставлять полный рабочий код, который вы копируете и вставляете без обучения. Вместо этого я объясню, что вам нужно сделать, шаг за шагом, чтобы вы могли написать код самостоятельно. Помните, Stackoverflow - это не служба написания кода.

Предлагаемое здесь решение основано на вашем комментарии:

код столбца (например, Column1) может отображаться для более чем одного источника code.

  1. Создайте словарь, пусть ключ будет кортежем, содержащим SourceCode и ColumnCode, а значение будет кортежем, содержащим SourceValue и ColumnValue.

  2. Предполагая, что каждая строка файла всегда имеет формат SourceCode ColumnCode Sourcevalue ColumnValue, я бы прочитал файл построчно, разделив его на массив из четырех строк (назовем массив splitted), добавьте кортеж (splitted[0], splitted[1]) (ключ) и (splitted[2], splitted[3] (значение) в словарь.

  3. Теперь у вас есть словарь, представляющий файл содержимое с доступом O (1).

  4. Давайте сделаем второе предположение, что ваша входная строка имеет формат anytext[Source1].[anytext:Column1:anytext]anytext. Я бы использовал Regex, чтобы получить Source1 и Column1 из строки, а затем получить соответствующие значения из словаря. И наконец сделаем замену.

0 голосов
/ 10 июля 2020
var source = "anytext[Source1].[anytext:Column1:anytext]anytext";
var src1 = "Source1";
var dest1 = "ABC";
var src2 = "Column1";
var dest2 = "Col1";

var result = source
                .Replace("[" + src1 + "]", "[" + dest1 +"]")
                .Replace(":" + src2 + ":", ":" + dest2 +":");

https://dotnetfiddle.net/5cRnYD

Конечно, вы можете использовать любой список / словарь / файл для значений sr c и dest.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...