簡體   English   中英

在文件中查找特定文本並將其替換

[英]Find specific text in a file and replace that

我正在構建一個WPF程序,該程序正在編輯模擬程序的保存文件,以使調整某些參數更加容易。 該(txt)文件的結構如下所示

{Verdieping 1}

A bunch of data

'Max'
15
20
10
]);

More data

{Verdieping 2}

A bunch of data

'Max'
25
10
40
20
]);

More data

{Verdieping 3}

etc.

因為我需要的列表名稱始終是'Max',所以我不能使用Replace("Old_Value", "New_Value"); 因此,我需要某種方式來找到標題{Verdieping 1},然后查找“ Max”,並將值記下來,直到達到“]);”,這樣我最終得到這樣的結果:

Verdieping_1[0] = 15
Verdieping_1[1] = 20
Verdieping_1[0] = 10

Verdieping_2[0] = 25
Verdieping_2[1] = 10
Verdieping_2[2] = 40
Verdieping_2[3] = 20

然后,當我更改這些值時,我需要將它們寫回到正確位置的文件中。 現在,我正在使用以下代碼來讀取並最終寫入新文件:

var Model = System.IO.File.ReadAllText(@"C:\Base_Model.txt");

//format code here...

System.IO.File.WriteAllText(@"C:\New_Model.txt", Model);

有人可以給我一些提示或幫助,讓我找到最好的解決方法嗎?

編輯這是我要編輯的文件的實際文件結構:

{Atom: Verdieping 2}

int015(0, 64, [ 
1
2
3
]);
int015(1, 64, [`ActivityID`
20
21
33
]);
int015(2, 64, [`vtp`
139830296
189540320
169919424
]);
int015(3, 64, [`%`
100
100
100
]);
int015(4, 64, [`Max`
15
5
20
]);
int015(5, 64, [`Fill (1 = fill, 0 = empty)`
1
1
0
]);
SetStatus(0);
int018;


{Atom: Verdieping 2}

int015(0, 64, [ 
1
2
3
]);
int015(1, 64, [`ActivityID`
22
23
24
]);
int015(2, 64, [`vtp`
166058172
165557860
155960564
]);
int015(3, 64, [`%`
100
100
100
]);
int015(4, 64, [`Max`
15
20
10
]);
int015(5, 64, [`Fill (1 = fill, 0 = empty)`
0
1
1
]);
SetStatus(0);
int018;

我之前所說的“ Max”實際上稱為:int015(4,64,[ Max

正如您所看到的,每個層的名稱相同,變量的數量也不同。

感謝你目前的幫助!

var result = Regex.Matches(File.ReadAllText(fileName), @"\[`Max`(.*?)\]", RegexOptions.Singleline)
            .Cast<Match>()
            .Select(m => m.Groups[1].Value.Split(" \t\n\r".ToArray(), StringSplitOptions.RemoveEmptyEntries))
            .ToList();

foreach (var v in result)
{
    Console.WriteLine(String.Join(", ", v));
}

輸出:

15, 5, 20
15, 20, 10

正則表達式也許? 我做了這個快速答案,但是不應復制粘貼。 您可以考慮結果。

在這個答案中,我希望您的數組按時間順序排列,以防止源代碼過長和混亂。

我為“ DataContainer”對象讀取的文件看起來與以下文件相同:

{Verdieping 1}

A bunch of data

'Max'
15
20
10
]);

More data

{Verdieping 2}

A bunch of data

'Max'
25
10
40
20
]);

首先,我在字符串中找到每個“ Max”,然后將下面的所有數據打印出來

用於查找此內容的正則表達式為: \\'Max\\'.*?\\]\\);

試用此代碼以查看結果

// fill our container
            string DataContainer = string.Empty;
            using (StreamReader sr = new StreamReader(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "TestFile.txt"))) {
                DataContainer = sr.ReadToEnd();
            }

            // print data
            Match regMatch = Regex.Match(DataContainer, @"\'Max\'.*?\]\);", RegexOptions.Singleline);
            int verdiepc = 0;
            while (regMatch.Success) {
                string[] Data = regMatch.Value.Replace("\r", "").Split('\n');

                for (int I = 1; I < Data.Length - 1; I++) {
                    Console.WriteLine("Verdieping_{0}[{1}] = {2}"
                        , verdiepc, I, Data[I]);
                }
                Console.Write("\n");

                verdiepc ++;
                regMatch = regMatch.NextMatch();
            }

            // prevent immidiate exit
            Console.ReadKey();

輸出將是:

Verdieping_0[1] = 15
Verdieping_0[2] = 20
Verdieping_0[3] = 10

Verdieping_1[1] = 25
Verdieping_2[2] = 10
........ etc..

希望您可以使用此答案。 它是如何使用Regex解析文件的草圖

        string LoadedFile = File.ReadAllText(@"C:\Base_Model.txt");
        StringBuilder result = new StringBuilder();
        for (int i = 1; i < Int32.MaxValue; i++)
        {
            Match ma = Regex.Match(LoadedFile, "Verdieping " + i.ToString() + ".+?'Max'.*?([0-9].+?)[]][)];", RegexOptions.Singleline);
            if(!ma.Success)
            {
                break;
            }
            string a = ma.Result("$1");
            MatchCollection mc = Regex.Matches(a, "(\\d+?)\r\n", RegexOptions.Singleline);

            for (int j = 0; j < mc.Count; j++)
            {
                result.AppendLine(String.Format("Verdieping_{0}[{1}] = {2}", i, j, mc[j].Result("$1")));
            }
            result.AppendLine(String.Empty);
        }

        File.WriteAllText(@"C:\New_Model.txt", result.ToString());

您可以初始化一個新的string List ,其中將包含所需的輸出。 然后,讀取文件以獲取目標節之間的信息,並在[]);之間插入值]); 進入string List

static List<string> ReadFile(string Path, string Section)
{
    #region Declare Variables
    string[] Lines = File.ReadAllLines(Path); //Read Path into Lines
    int CurrentValue = 1; //Declare CurrentValue as an Integer of value 1
    List<string> RequiredValues = new List<string>(); //Initialize a new List of string of name RequiredValues
    #endregion
    #region Collect Information
    //Look through the section getting the data between [ and ]);
    for (int i = 0; i < Lines.Length; i++)
    {
        if (Lines[i].StartsWith("{" + Section + "}"))
        {
            i++;
            while (!Lines[i].StartsWith("{") && !Lines[i].EndsWith("}"))
            {
                i++;
                if (Lines.Length > i)
                {
                    if (Lines[i].Contains('['))
                    {
                        while (true)
                        {

                            i++;
                            if (Lines[i].Contains("]);"))
                            {
                                break;
                            }
                            RequiredValues.Add(Section + "[" + CurrentValue.ToString() + "] = " + Lines[i]);
                            CurrentValue++;
                        }
                    }
                    RequiredValues.Add("");
                }
                else
                {
                    break; //Reached the end of the document
                }
            }
        }
    }
    #endregion
    return RequiredValues; //Return RequiredValues
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
    List<string> Contents = ReadFile(@"C:\Base_Model.txt", "Atom: Verdieping 2");
    foreach (string str in Contents)
    {
        System.Diagnostics.Debug.WriteLine(str); //Write str to the trace listeners
    }
}

樣本輸入

{Atom: Verdieping 2}

int015(0, 64, [ 
4
5
6
]);
int015(1, 64, [`ActivityID`
20
21
33
]);
int015(2, 64, [`vtp`
139830296
189540320
169919424
]);
int015(3, 64, [`%`
100
100
100
]);
int015(4, 64, [`Max`
15
5
20
]);
int015(5, 64, [`Fill (1 = fill, 0 = empty)`
1
1
0
]);
SetStatus(0);
int018;

{Atom: Verdieping 1}

int015(0, 64, [ 
1
2
3
]);
int015(1, 64, [`ActivityID`
22
23
24
]);
int015(2, 64, [`vtp`
166058172
165557860
155960564
]);
int015(3, 64, [`%`
100
100
100
]);
int015(4, 64, [`Max`
15
20
10
]);
int015(5, 64, [`Fill (1 = fill, 0 = empty)`
0
1
1
]);
SetStatus(0);
int018;

樣本輸出

通過閱讀Atom: Verdieping 2返回了以下內容Atom: Verdieping 2

Atom: Verdieping 2[1] = 4
Atom: Verdieping 2[2] = 5
Atom: Verdieping 2[3] = 6

Atom: Verdieping 2[4] = 20
Atom: Verdieping 2[5] = 21
Atom: Verdieping 2[6] = 33

Atom: Verdieping 2[7] = 139830296
Atom: Verdieping 2[8] = 189540320
Atom: Verdieping 2[9] = 169919424

Atom: Verdieping 2[10] = 100
Atom: Verdieping 2[11] = 100
Atom: Verdieping 2[12] = 100

Atom: Verdieping 2[13] = 15
Atom: Verdieping 2[14] = 5
Atom: Verdieping 2[15] = 20

Atom: Verdieping 2[16] = 1
Atom: Verdieping 2[17] = 1
Atom: Verdieping 2[18] = 0

讀取Atom: Verdieping 1返回了以下輸出Atom: Verdieping 1

Atom: Verdieping 1[1] = 1
Atom: Verdieping 1[2] = 2
Atom: Verdieping 1[3] = 3

Atom: Verdieping 1[4] = 22
Atom: Verdieping 1[5] = 23
Atom: Verdieping 1[6] = 24

Atom: Verdieping 1[7] = 166058172
Atom: Verdieping 1[8] = 165557860
Atom: Verdieping 1[9] = 155960564

Atom: Verdieping 1[10] = 100
Atom: Verdieping 1[11] = 100
Atom: Verdieping 1[12] = 100

Atom: Verdieping 1[13] = 15
Atom: Verdieping 1[14] = 20
Atom: Verdieping 1[15] = 10

Atom: Verdieping 1[16] = 0
Atom: Verdieping 1[17] = 1
Atom: Verdieping 1[18] = 1

注意 :使用此方法,即使您有兩個具有相同名稱的部分,應用程序也只會在遇到的第一部分之間收集信息。

謝謝,
我希望這個對你有用 :)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM