【问题标题】:String pattern search and replace in C#C#中的字符串模式搜索和替换
【发布时间】:2020-07-10 22:43:36
【问题描述】:

我遇到一个文本文件有很多字符串的情况,如下所示。我需要搜索这些模式并用值替换源代码和列代码。请问我们如何在 C# 中进行这种字符串模式搜索和替换?谢谢。

实际文本:“anytext[Source1].[anytext:Column1:anytext]anytext”

更新文本:“anytext[ABC].[anytext:Col1:anytext]anytext”

代码和值组合如下所示。

SourceCode ColumnCode 源值列值

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

Source1 Column1 ABC Col1

Source2 Column2 DEF Col2

Source3 Column3 GHI Col3

【问题讨论】:

  • 您能否提供这样一个代码的结构(一个示例)以及一个您希望将其替换为的值的示例?看起来 Regex 可以为您完成这项工作,但我们至少需要代码字段的结构
  • 您想知道什么是 Code1/Code2 并用某种字典中的值替换吗?或者 Code1 和 Code2 是静态字符串?
  • 好吧,我认为他从哪里获取值(存储关联的位置)并不重要,他说他想找到并替换那些“代码”,但为此,在为了至少使用正则表达式,我们需要“代码”的结构
  • @GabrielStancu 谢谢。我已经编辑了添加示例值的问题。所以我在表中有源代码和列代码,我必须在字符串模式中找到组合并将它们替换为值。
  • 我不确定您对编辑的意思。 ====== 上面的那一行是要被它下面的行中的值替换的代码吗?

标签: c#


【解决方案1】:

我使用两个单独的字典来关联源字段和列字段,因为我认为关联仅在源字段和列字段之间。示例代码是为一个按钮制作的,当它被单击时替换标签的文本,但它可以适应任何类似的情况。到目前为止,这是我想出的:

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 部分只能包含字母数字文本,如果在那里可以找到其他字符,我将编辑正则表达式模式。

【讨论】:

  • 感谢您的帮助。我能够使代码正常工作并将其发布以供参考。
【解决方案2】:

我不会提供完整的工作代码,您无需学习即可复制和粘贴它。相反,我将逐步解释您需要做什么,以便您能够自己编写代码。请记住,Stackoverflow 不是代码编写服务。

此处提供的解决方案基于您的评论:

列代码(例如 Column1)可以出现在多个源代码中。

  1. 创建一个字典,让键是一个包含SourceCodeColumnCode的元组,值是一个包含SourceValueColumnValue的元组。

  2. 假设文件的每一行总是SourceCode ColumnCode Sourcevalue ColumnValue的格式,我会逐行读取文件,将其拆分为四个字符串的数组(我们称之为数组splitted),添加元组(splitted[0], splitted[1])(键)和(splitted[2], splitted[3](值)到字典中。

  3. 现在,您有一个字典,表示具有 O(1) 访问权限的文件内容。

  4. 让我们做第二个假设,即您的输入字符串的格式为anytext[Source1].[anytext:Column1:anytext]anytext。我会使用正则表达式从字符串中获取Source1Column1,然后从字典中获取相应的值。最后进行替换。

【讨论】:

  • 谢谢。我遵循了您建议的方法并使其与正则表达式一起使用!我也会发布代码以供参考。
【解决方案3】:

只需发布我使用@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);
            }

【讨论】:

    【解决方案4】:
    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

    当然,您可以将任何列表/字典/文件用于 src 和 dest 值。

    【讨论】:

    • 谢谢,但我拥有的来源是一个巨大的文本,它可能有多次使用“[Source1].[anytext:Column1:anytext]”的模式。所以我想要一个正则表达式来找出大文本中的每个模式,然后只对这些模式字符串执行替换选项。
    猜你喜欢
    • 2010-09-10
    • 1970-01-01
    • 1970-01-01
    • 2015-05-26
    • 1970-01-01
    • 1970-01-01
    • 2020-12-25
    相关资源
    最近更新 更多