2011-06-25 37 views
3

我有一個包含文本的文件。現在,我必須用另一個替換一些字符串。例如,我不得不更換c#替換包含未知部分的字符串

"[ContactLetterSalutation]" 

"Dear Thomas Kehl". 

現在,它是可能的是,佔位符"[ContactLetterSalutation]"包含地方"=\r\n" - 這可能是一個,兩個或更多的時間 - 例如

"[Conta=\r\ntLetterSa=\r\nlutation]". 

我現在正在尋找一種方式,我也可以取代這個 - 我不知道在哪裏,有多少次會有"=\r\n"。困難的是,我不應該在文中替換所有出現的"=\r\n"。有人可以幫助我如何做到這一點? RegEx有可能做到這一點嗎?

謝謝。 托馬斯

回答

6
string GetReplacement(Match m) { 
    // Get the matched string. 
    string x = m.ToString().Replace("=\r\n",""); 
    return Lookup[x]; 
} 

... 
file = Regex.Replace(file, @"\[.*?\]", GetReplacement, RegexOptions.Singleline); 
編輯:

RegexOptions.Singleline原因。以匹配\ n

編輯2:

雖然上述應該適用於小文件,但我認爲這個問題對於無法將整個文件整合到一個字符串中的流更有趣。我想出了這個,但它可能有錯誤:

static IEnumerable<string> Chunk(TextReader reader) { 
    char[] chars = new char[MaxBufferSize]; 
    string buffer = ""; 
    int charsRead; 
    while ((charsRead = reader.ReadBlock(chars, 0, MaxBufferSize)) > 0) { 
     buffer = buffer + new string(chars,0,charsRead); 
     int indexOfOpenBracket; 
     if((indexOfOpenBracket = buffer.IndexOf('[')) == -1) { 
      if (!string.IsNullOrEmpty(buffer)) yield return buffer; 
      buffer = ""; 
      continue; 
     } 
     while (indexOfOpenBracket!=-1) { 
      string outsideBrackets = buffer.Substring(0, indexOfOpenBracket); 
      if(!string.IsNullOrEmpty(outsideBrackets)) yield return outsideBrackets; 
      buffer = buffer.Substring(indexOfOpenBracket + 1); 
      int indexOfCloseBracket = buffer.IndexOf(']'); 
      if (indexOfCloseBracket != -1) { 
       string insideBrackets = buffer.Substring(0, indexOfCloseBracket); 
       buffer = buffer.Substring(indexOfCloseBracket + 1); 
       yield return DoLookup(insideBrackets); 
      } else { 
       buffer = '[' + buffer; 
       break; 
      } 
      indexOfOpenBracket = buffer.IndexOf('['); 
     } 
    } 
    yield return buffer; 
} 
public static void BufferReplace(Stream input, Stream output) { 
    StreamReader reader = new StreamReader(input); 
    StreamWriter writer = new StreamWriter(output); 
    foreach (var chunk in Chunk(reader)) { 
     writer.Write(chunk); 
    } 
    writer.Flush(); 
} 
+0

這是Sjoerd的答案的代碼版本;我得到了忍者,並沒有留意。我會離開它,但標記他是正確的。 –

+0

比爾的答案是相當的,但比我的更優雅。只要確保如果你使用他的正則表達式,你正在查找的模式具有[和]在其中或使用組,如我所描述的。 – Rob

+0

嗨比爾。謝謝。但有一個問題。 \ r \ n是一個LineBreak - 現在您的RegEx-Pattern沒有找到它。我必須改變什麼,RegEx-Pattern還會在[]中找到包含LineBreak的模式? – BennoDual

6
  • 使用正則表達式在括號內搜索任何內容。
  • 對於每一個匹配,刪除所有= \ r \ n找到密鑰。
  • 用值替換匹配。

例子:

  • 您搜索[什麼]
  • 您找到[Conta=\r\ntLetterSa=\r\nlutation]
  • 您使用密鑰ContatLetterSalutation來查找正確的值。
  • 用此值替換[Conta=\r\ntLetterSa=\r\nlutation]
1

是的,你可以用正則表達式來做到這一點。我不會試圖讓這一切發生。我假設你有一個HashTable或其他存儲,你可以在其中查找佔位符字符串來獲取你想放置的文本。另外我假設你想從C#代碼做到這一點,有一個工具調用sed,可以從unix/linux或cygwin的Windows下的命令行執行此操作。它與正則表達式一起工作。

工作了正則表達式時,我喜歡使用這個網站:http://regexpal.com/

所以首先你嘗試並找到與不必要的\ r \ n在它的佔位符的模式:「\ [([^ \ ]] +)\]「這將找到任何以[至少有一個不是]並以]結尾的字符開頭的模式。

一旦你有你可以使用的匹配列表,刪除你不想要的模式,然後用它來查找。

這裏是一個非常簡單的小例子:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Text.RegularExpressions; 

namespace ConsoleApplication2 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      String textFromFile = "some text [re=\r\npla=\r\nme] more [Anoth=\r\ner=\r\n place=\r\n=\r\n=\r\n holder] text"; 

      foreach (Match match in Regex.Matches(textFromFile, "\\[([^\\]]+)\\]")) 
      { 
       String placeHolder = match.Groups[1].Value.Replace("=\r\n", ""); 
       // *** Do rest of your work here ***. 
       System.Console.WriteLine(placeHolder); 
      } 
     } 
    } 
} 

這個程序打印出:

replaceme 
Another place holder