2010-04-08 42 views
1

我發送郵件(在asp.net,C#)找到一個特定的詞,具有類似於下面如何在一個文本文件中使用.NET

User Name :<User Name> 

Address : <Address>. 

我在文本文件(.txt)模板使用使用下面的代碼

StreamReader sr; 
sr = File.OpenText(HttpContext.Current.Server.MapPath(txt)); 

copy = sr.ReadToEnd(); 

sr.Close(); //close the reader 

copy = copy.Replace(word.ToUpper(),"#" + word.ToUpper()); //remove the word specified UC 


//save new copy into existing text file 

FileInfo newText = new FileInfo(HttpContext.Current.Server.MapPath(txt)); 

StreamWriter newCopy = newText.CreateText(); 
newCopy.WriteLine(copy); 
newCopy.Write(newCopy.NewLine); 
newCopy.Close(); 

現在我有一個新的問題來代替尖括號內的詞語的文本文件,

用戶將一個角度內添加新詞,譬如說例如,他們將加入<Salary>.

在這種情況下,我必須讀出並查找單詞<Salary>.

換句話說,我必須找到所有的話,在位於與所述角撐架(<>)。

我該怎麼做?

回答

1

這不是一個答案,但評論不能做到這一點:

你應該把你的一些對象爲using塊。事情是這樣的:

using(StreamReader sr = File.OpenText(HttpContext.Current.Server.MapPath(txt))) 
{ 
    copy = sr.ReadToEnd(); 
} // reader is closed by the end of the using block 

//remove the word specified UC 
copy = copy.Replace(word.ToUpper(), "#" + word.ToUpper());  

//save new copy into existing text file 

FileInfo newText = new FileInfo(HttpContext.Current.Server.MapPath(txt)); 

using(var newCopy = newText.CreateText()) 
{ 
    newCopy.WriteLine(copy); 
    newCopy.Write(newCopy.NewLine); 
} 

using塊確保資源的及時清理,即使拋出一個異常。

2

使用正則表達式。

var matches = Regex.Matches(text, "<(.*?)>"); 
List<string> words = new List<string>(); 

for (int i = 0; i < matches.Count; i++) 
{ 
    words.Add(matches[i].Groups[1].Value); 
} 

當然,這假定你已經在一個變量文件的文本。由於您必須閱讀整個文件才能實現該目標,因此您可以在閱讀流時查找這些文字,但我不知道性能會受到什麼影響。

+0

喬爾,你的假設是給定的,將正則表達式比字符串替換或字符串格式更快? – Pierreten 2010-04-08 01:33:38

+0

@Joel我認爲你的意思是'。*?' – 2010-04-08 02:21:55

+0

謝謝艾哈邁德。 @Pierreten,除非你提前知道這些單詞,否則你將無法使用替換。 – Joel 2010-04-08 13:37:11

2

爲您的文件創建一個流,您可以構建類似於典型標記器的東西。一般來說,這是一個有限狀態機:你需要一個枚舉狀態(在這種情況下可以簡化爲一個布爾值,但我會給你一般方法,所以你可以重用它類似的任務);和一個實現邏輯的功能。 C#的迭代器非常適合這個問題,所以我將在下面的代碼片段中使用它們。你的函數將把流作爲參數,在內部使用一個枚舉值和一個char緩衝區,並且會逐個產生字符串。你需要這個代碼文件的開頭附近:

using System.Collections.Generic; 
using System.IO; 
using System.Text; 

然後,你的類中,這樣的事情:

enum States { 
    OUT, 
    IN, 
} 
IEnumerable<string> GetStrings(TextReader reader) { 
    States state=States.OUT; 
    StringBuilder buffer; 
    int ch; 
    while((ch=reader.Read())>=0) { 
     switch(state) { 
      case States.OUT: 
       if(ch=='<') { 
        state=States.IN; 
        buffer=new StringBuilder(); 
       } 
       break; 
      case States.IN: 
       if(ch=='>') { 
        state=States.OUT; 
        yield return buffer.ToString(); 
       } else { 
        buffer.Append(Char.ConvertFromUtf32(ch)); 
       } 
       break; 
     } 
    } 
} 

的有限狀態機模型總是具有相同的佈局: while(READ_INPUT) { switch(STATE) {...}}:在開關的每種情況下,您可能正在產生輸出和/或改變狀態。除此之外,算法是根據狀態和狀態變化來定義的:對於任何給定的狀態和輸入組合,都有一個確切的新狀態和輸出組合(在沒有觸發輸出的狀態下,輸出可以是「無」;而如果沒有狀態改變被觸發,則狀態可以是相同的舊狀態)。

希望這會有所幫助。

編輯:忘了提一兩件事情:

1)你得到的TextReader通過創建一個文件一個StreamReader,或StringReader如果你已經有了一個字符串的文件傳遞給函數。

2)這種方法的內存和時間成本是O(n),其中n是文件的長度。這類任務看起來很合理。

+1

這正是我在回答中所指的。很高興看到這個與正則表達式方法的基準。 – Joel 2010-04-08 13:40:50