2014-10-30 133 views
0

我在用字典中的值替換字符串中的單詞時出現了一些問題。這裏是我當前的代碼一個小樣本:字符串用字典值替換

Dictionary<string, string> replacements = new Dictionary<string, string>() 
{ 
    {"ACFT", "AIRCRAFT"}, 
    {"FT", "FEET"}, 
}; 
foreach(string s in replacements.Keys) 
{ 
    inputBox.Text = inputBox.Text.Replace(s, replacements[s]); 
} 

當我執行的代碼,如果我有在文本框中ACFT,它會被替換AIRCRAFEET,因爲它看到字符串中的FT部分。我需要以某種方式區分這一點,只取代整個單詞。

例如,如果我在框中有ACFT,應該用AIRCRAFT代替它。而且,如果我在框中有FT,請用FEET替換它。

所以我的問題是,我怎樣才能匹配整個單詞只有當替換單詞?

編輯:我想能夠使用和替換多個單詞。你修改你的問題..

string str = "ACFT FTT"; 
Dictionary<string, string> replacements = new Dictionary<string, string>() 
{ 
    {"ACFT", "AIRCRAFT"}, 
    {"FT", "FEET"}, 
}; 
string[] temp = str.Split(' '); 
string newStr = ""; 
for (int i = 0; i < temp.Length; i++) 
{ 

    try 
    { 
     temp[i] = temp[i].Replace(temp[i], replacements[temp[i]]); 
    } 
    catch (KeyNotFoundException e) 
    { 
     // not found.. 
    } 
    newStr+=temp[i]+" "; 
} 
Console.WriteLine( newStr); 
+3

嘗試看看這個http://stackoverflow.com/questions/6143642/way-to-have-string-replace-only-hit-全字 – 2014-10-30 05:46:31

+0

我編輯了你的標題。請參閱:「[應該在其標題中包含」標籤「](http://meta.stackexchange.com/questions/19190/)」,其中的共識是「不,他們不應該」。 – 2014-10-30 06:20:14

回答

0

使用if條件..

foreach(string s in replacements.Keys) { 
    if(inputBox.Text==s){ 
     inputBox.Text = inputBox.Text.Replace(s, replacements[s]); 
    } 
} 

UPDATE後,這裏的問題是,你在更換子的每個實例整個字符串。如果您想要替換「ACFT」或「FT」的整個空格分隔的實例,則需要使用String.Split()創建一組標記。

例如:

string tempString = textBox1.Text; 
StringBuilder finalString = new StringBuilder(); 
foreach (string word in tempString.Split(new char[] { ' ' }) 
{ 
    foreach(string s in replacements.Keys) 
    { 
     finalString.Append(word.Replace(s, replacements[s])); 
    } 
} 

textBox1.Text = finalString.ToString(); 

我這裏用一個StringBuilder因爲級聯需要創建一個新的字符串的每一次,這變得非常低效過很長時間。如果你期望有少量的連接,你可能會逃避使用字符串。

請注意,您的設計中存在輕微的皺摺 - 如果您的KeyValuePair的值與字典迭代中稍後出現的某個鍵的值相同,則替換將被覆蓋。

+0

只有當他們在文本框中輸入單個單詞 – 2014-10-30 05:47:11

+0

時,他纔會使用他正在說一個單詞直到還沒有..檢查他給了什麼樣的例子..在我回答的基礎上..如果仔細閱讀答案,必須仔細閱讀問題那.. – 2014-10-30 05:48:36

+0

謝謝你的建議,Deepak。我原來的問題應該更加清楚;但是,如果我確實有多個單詞,則您的解決方案不起作用。 – Nicholas 2014-10-30 05:50:36

0

+0

我thnk你的列表將是 ** Console.WriteLine(s.Replace(s,replacementments [s])); ** – 2014-10-30 05:50:11

+0

aaha刪除代碼.. – 2014-10-30 05:50:31

+0

@DeepakSharma我誤解了請求 - 現在編輯 – furkle 2014-10-30 05:50:33

0

我想你可能想要替換inputText中的最大長度subStr。

 int maxLength = 0; 
     string reStr = ""; 
     foreach (string s in replacements.Keys) 
     { 
      if (textBox2.Text.Contains(s)) 
      { 
       if (maxLength < s.Length) 
       { 
        maxLength = s.Length; 
        reStr = s; 
       } 
      } 
     } 
     if (reStr != "") 
      textBox2.Text = textBox2.Text.Replace(reStr, replacements[reStr]); 
1

我怎麼能全字匹配只有更換時的話嗎?

使用正則表達式(如由大衛·皮爾金頓建議)

Dictionary<string, string> replacements = new Dictionary<string, string>() 
{ 
    {"ACFT", "AIRCRAFT"}, 
    {"FT", "FEET"}, 
}; 

foreach(string s in replacements.Keys) 
{ 
    var pattern = "\b" + s + "\b"; // match on word boundaries 
    inputBox.Text = Regex.Replace(inputBox.Text, pattern, replacements[s]); 
} 

但是,如果你有控制權的設計,我寧願使用鍵像"{ACFT}""{FT}"(有明確的界限),所以你可以使用String.Replace

0

這是非常時髦的做法。

首先,您需要使用正則表達式(Regex),因爲它具有良好的內置特徵以匹配單詞邊界。

這樣的代碼重點線將是定義一個Regex實例:

var regex = new Regex(String.Format(@"\b{0}\b", Regex.Escape("ACFT")); 

\b標記查找單詞邊界。 Regex.Escape確保如果其他任何密鑰有特殊的Regex字符,則它們將被轉義。

然後,您可以替換這樣的文字:

var replacedtext = regex.Replace("A FT AFT", "FEET"); 

你會得到replacedtext == "A FEET AFT"

現在,這裏是時髦的部分。如果你從當前的字典開始,那麼你可以定義一個函數,一次完成所有的替換。

這樣來做:

Func<string, string> funcreplaceall = 
    replacements 
     .ToDictionary(
      kvp => new Regex(String.Format(@"\b{0}\b", Regex.Escape(kvp.Key))), 
      kvp => kvp.Value) 
     .Select(kvp => 
      (Func<string, string>)(x => kvp.Key.Replace(x, kvp.Value))) 
     .Aggregate((f0, f1) => x => f1(f0(x))); 

現在你可以叫它像這樣:

inputBox.Text = funcreplaceall(inputBox.Text); 

無循環所需!

正如合理性檢查,我得到這個:

funcreplaceall("A ACFT FT RACFT B") == "A AIRCRAFT FEET RACFT B"