iT邦幫忙

0

[C#超新手]想請問如何編輯文字檔並插入特定字串在特定位置?

各位大大晚上好,小弟因為工作需要,最近想寫一個自動化的程式來幫助編輯txt文字檔,但因為是前幾天才開始接觸程式語言(目前只有五天左右的基礎),所以想來這個寶地向各位高手請教,很希望可以有高人指點一下迷津,感激不盡!!! 以下大概形容一下我的狀況,希望描述得夠清楚,如果有高手願意指導又看不懂,麻煩請讓我知道,謝謝!!

我的需求是這樣,就是不定時會有不同的文字檔需要加入資訊,而這些加入的資訊又需要根據文字檔裡的特定字串做改寫,例如:
原始文字檔的內容是不規則的一堆文字
AAAA0001;
AAAA0002;

BBBBBB000001;
BBBBBB000002;
BBBBBB000003;
(依此類推,另外文檔中間還有很多其他的敘述),
而我需要將這類型的字串,在前段插入不同專案代號(V#)、後段固定插入1234跟對應的專案另一個代號(P#),並在前端加上分隔線,並且這個專案數#是日後有可能會再增加的

而在修改的文字檔裡,專案1-3 只對應AAAA,專案4-5 只對應BBBBBB,另外修改後要用分隔線隔開、並且排序修改過的字串,更改後大致像這樣:

==For #1==;
AAAA_V1_00011234_P1;
AAAA_V1_00021234_P1;

==For #2==;
AAAA_V2_00011234_P2;
AAAA_V2_00021234_P2;

==For #3==;
AAAA_V3_00011234_P3;
AAAA_V3_00021234_P3;

==For #4==;
BBBBBB_V4_0000011234_P4;
BBBBBB_V4_0000021234_P4;
BBBBBB_V4_0000031234_P4;

==For #5==;
BBBBBB_V5_0000011234_P5;
BBBBBB_V5_0000021234_P5;
BBBBBB_V5_0000031234_P5;

在這一週爬了很多文章後,大概理解到的方法是如下,可是像插入分隔線+重新排序這個部份暫時還不太確定要怎麼實現,不知道C#有沒有辦法做到這樣的排序功能?

  1. 先建立一個配對#物件的矩陣,將V#、P#設為建構子的string變數,1234則寫成固定的int
  2. 應該是有辦法把AAAA、BBBBBB的判斷式也寫成物件的矩陣,因為另外還有CCC、DDDD之類的判斷要一直加進去,但目前還在想物件內容怎麼寫
  3. 程式碼我應該下週會寫好,如果有大大願意幫忙指導我會再po出來,謝謝

https://ithelp.ithome.com.tw/upload/images/20200510/201269909zoX9b1MXu.jpg

=====5/12更新的內容=====
感謝各位大大幫忙回覆,目前已經成功可以完成修改並輸出新檔了~~~多謝大家幫忙!!

jay91385 iT邦新手 5 級 ‧ 2020-05-11 10:39:03 檢舉
此留言已經修改移至下方回答處
3
海綿寶寶
iT邦大神 1 級 ‧ 2020-05-10 09:39:45
最佳解答

不同的文字檔需要加入資訊,而這些加入的資訊又需要根據文字檔裡的特定字串做改寫

簡單提出幾個疑問
1.若原始檔案是 IN01.txt
那經過程式處理之後
會是 IN01.txt(內容不變) 加上另一個 OUT01.txt
還是 IN01.txt(內容改變)
2.如果是「IN01.txt(內容不變) 加上另一個 OUT01.txt」
那程式中就不必判斷「字串包含1234」
因為原始的 IN01.txt 中不會有 1234 (或P#)
除非
還有可能處理 IN01.txt「一次以上」
如果真的會處理 IN01.txt 一次以上
1234/P# 也不能不處理
也得放進你的矩陣裡以便之後「排序」
3.如果是「IN01.txt(內容改變)」
那麼「文檔中間還有很多其他的敘述」程式要如何處理
(因為許多列文字都因排序而有可能換了前後位置)
4.專案1-3 只對應AAAA,專案4-5 只對應BBBBBB
這個資訊要儲存在那裡給程式使用?
寫死/存資料庫/另外存文字檔?

另外
畫流程圖是很好
但流程圖只畫了「判斷字串並做相對處理」的部份
就可以由這裡看出目前的思考範圍

Ottis iT邦新手 5 級 ‧ 2020-05-11 21:29:22 檢舉

感謝大大的回應,我其實當天就打了回覆結果後來發現要達到一定條件才能回應...

  1. 我的確是要輸出成不同的檔案(Fron IN01.txt to OUT01.txt),抱歉當初沒有說明清楚
  2. 我的想法是因為AAA001有可能要判斷多次 (先給#1判斷完後,換#2判斷),不過經您這樣一提醒這個想法似乎有漏洞,現在還在思考怎麼做會比較好
  3. 因為這些條件只有特定的字串會滿足,所以其他不符條件的字串應該就忽略然後直接輸出 (我的想法是這樣啦~~:P)
  4. 這個我目前是想要用物件矩陣的方式儲存,不過還在努力看怎麼寫
  5. 我本來想說只要可以克服我畫出流程圖的部份,剩下的應該不是問題,不過現在發現第二步有漏洞,可能會重新思考流程

很謝謝幫忙提供一些思路,對我重新構想這些邏輯幫助很大,但因為真的是超新手,所以很多地方還是不熟,請多包含

看得出來你跟許多其他發問者相比
已經想得很多了
祝你好運

Ottis iT邦新手 5 級 ‧ 2020-05-12 21:14:18 檢舉

大大,我有上傳我目前可以輸出的結果(大略的),但是還是不確定要怎麼輸出成新的文檔,參考過網路用矩陣存文字檔再輸出的教學,並可以寫出下面的範例,可是套用到我目前使用的判斷式,就不知道要怎麼加進去...不知道大大有沒有比較好的建議,謝謝~~!

private void ReplaceItemName()
{
    string a = File.ReadAllText(@"c:\a.txt");
    string[] aText = a.Split('\t');
    string fileText = a;
    for (int i = 0; i < aText.Length; i++)
    {
            fileText = aText[i] + "test"; 
    }
    File.WriteAllText(@"c:\c.txt", fileText);
}
1
鬼王很慘
iT邦新手 5 級 ‧ 2020-05-10 11:22:20

我不會C#,只會Java,不過流程應該類似。

  1. 讀取txt文字檔案
    IO

  2. 獲得每一行字串
    就你所述,文字檔的內容不規則,有特定字串也有其他敘述。
    所以你在獲得行字串後要先判斷是否為你要處理的字串,不是則跳下一行。
    但一般建議文字檔案每一行都是要處理的比較單純。

  3. 拆分字串
    你給的例子AAAA0001要分為AAAA與0001。
    BBBBBB000001要分為BBBBBB與000001。
    你必須給予適當split邏輯,因為檔案還有其他部分。

  4. 判斷字串
    判斷英文字部分是AAAA或BBBBBB或其他。

  5. 處理字串

    • 插入分隔線與#數字
    • 將數字部分排序000001、000002...
    • 重組字串:英文字 + 底線 + V# + 底線 + 數字 + 1234 + 底線 + P#

大guy4醬

Ottis iT邦新手 5 級 ‧ 2020-05-11 21:32:06 檢舉

感謝大大的回覆,一樣其實我當天就回應了結果帳號權限不足所以現在才發現~~:P
2. 這點感謝提醒,目前的確是用每行處理比較符合思路!!
3&4&5. 其實原始字串比我提供的範例複雜很多,而且組成是不規則的字母加數字...不過我會想一下split在這邊是不是有其他的作用,感謝大大幫忙

Ottis iT邦新手 5 級 ‧ 2020-05-12 21:06:35 檢舉

感謝大大的連結,不過因為我這是先讀出原始字串、在過程中經過修改,然後再輸出到新的文字檔。我還在研究要怎麼一開始就先將文字檔存入字串、中間修改後再輸出到新的文檔,或是大大有範本可以供參考就更好了,感謝!!

0
jay91385
iT邦新手 5 級 ‧ 2020-05-11 10:40:14

我是建議,你的思維可以不要考慮 "把A改成B",這樣你會覺得很複雜

應該要往這個方向思考:
把A讀出來(到記憶體),"重新產生"一組B,再寫回檔案直接覆蓋原本檔案

Ottis iT邦新手 5 級 ‧ 2020-05-11 21:32:55 檢舉

感謝您的指教,是的現在的確是用讀出->修改成新字串->寫入的邏輯在進行~~~感謝大大

Ottis iT邦新手 5 級 ‧ 2020-05-12 21:11:53 檢舉

Jayy大請問您指的是將文字檔存成矩陣,在中間呼叫編輯後再存入到新的文字檔嗎?參考很多網上的分享可是有點卡住。我用下面的語法是可以輸出並存到新檔,可是套用到我原本文章裡的那些if判斷式,就不知道要怎麼把每個結果存成陣列再輸入...希望可以得到大大的指點,謝謝!!

    private void ReplaceItemName()
    {
        string a = File.ReadAllText(@"c:\a.txt");
        string[] aText = a.Split('\t');
        string fileText = a;
        for (int i = 0; i < aText.Length; i++)
        {
                fileText = aText[i] + "test"; 
        }
        File.WriteAllText(@"c:\c.txt", fileText);
    }

我要發表回答

立即登入回答