2013-08-04 88 views
7

我想知道如何從字符串中替換(移除)多個單詞(如500+)。我知道我可以使用替換功能爲單個單詞執行此操作,但如果要替換500多個單詞怎麼辦?我有興趣從文章中刪除所有通用關鍵字(例如「and」,「I」,「you」等)。如何用C#替換字符串中的多個單詞?

這裏是1個替換代碼..我希望做500+ ..

 string a = "why and you it"; 
     string b = a.Replace("why", ""); 
     MessageBox.Show(b); 

感謝

@謝爾蓋·庫徹文字大小几百字之間的變化非常小千。我正在從隨機文章中取代這些詞。

+0

您替換的文本的大小是多少? –

+0

我的回答有幫助嗎?如果你需要更復雜的東西,請告訴我。 –

+0

是不是用於停用詞表? –

回答

0

創建一個你想要的所有文本的列表並將其加載到一個列表中,你這樣做很簡單或變得非常複雜。一個簡單的例子是:

var sentence = "mysentence hi"; 
var words = File.ReadAllText("pathtowordlist.txt").Split(Enviornment.NewLine); 
foreach(word in words) 
    sentence.replace("word", "x"); 

如果你想要一個雙重映射方案,你可以創建兩個列表。如果你想與其他文本替換文本

string text = "word1 word2 you it"; 
List<string> words = new System.Collections.Generic.List<string>(); 
words.Add("word1"); 
words.Add("word2"); 
words.ForEach(w => text = text.Replace(w, "")); 

編輯

,您可以創建類單詞

+0

低效,字符串len M,字數= N這是O( N * M) 並且可以製成O(M)。 –

+0

這確實是不合適的 - 但它會根據要求完成工作。如果你有更好的解決方案 - 我很高興看到它! –

+0

起初,我以爲我有,並開始寫它,但我發現它也是O(NM),也許有點少開銷,但仍然,所以我把我的話回來...這是最容易的 –

0

試試這個

public class Word 
{ 
    public string SearchWord { get; set; } 
    public string ReplaceWord { get; set; } 
} 

和更改上面的代碼對此:

string text = "word1 word2 you it"; 
List<Word> words = new System.Collections.Generic.List<Word>(); 
words.Add(new Word() { SearchWord = "word1", ReplaceWord = "replaced" }); 
words.Add(new Word() { SearchWord = "word2", ReplaceWord = "replaced" }); 
words.ForEach(w => text = text.Replace(w.SearchWord, w.ReplaceWord)); 
7

我通常會做這樣的事情:

// If you want the search/replace to be case sensitive, remove the 
// StringComparer.OrdinalIgnoreCase 
Dictionary<string, string> replaces = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase) { 
    // The format is word to be searched, word that should replace it 
    // or String.Empty to simply remove the offending word 
    { "why", "xxx" }, 
    { "you", "yyy" }, 
}; 

void Main() 
{ 
    string a = "why and you it and You it"; 

    // This will search for blocks of letters and numbers (abc/abcd/ab1234) 
    // and pass it to the replacer 
    string b = Regex.Replace(a, @"\w+", Replacer); 
} 

string Replacer(Match m) 
{ 
    string found = m.ToString(); 

    string replace; 

    // If the word found is in the dictionary then it's placed in the 
    // replace variable by the TryGetValue 
    if (!replaces.TryGetValue(found, out replace)) 
    { 
     // otherwise replace the word with the same word (so do nothing) 
     replace = found; 
    } 
    else 
    { 
     // The word is in the dictionary. replace now contains the 
     // word that will substitute it. 

     // At this point you could add some code to maintain upper/lower 
     // case between the words (so that if you -> xxx then You becomes Xxx 
     // and YOU becomes XXX) 
    } 

    return replace; 
} 

至於別人寫的,但沒有問題的子串(的ass原則......你不想從CL ass ES刪除ass ES: - )),只有工作,如果你只需要刪除的話:

var escapedStrings = yourReplaces.Select(Regex.Escape); 
string result = Regex.Replace(yourInput, @"\b(" + string.Join("|", escapedStrings) + @")\b", string.Empty); 

我用\b字邊界......這是一個有點複雜的解釋那是什麼,而是找字邊界是非常有用:-)

+0

創建Regex實例更爲理想,重新使用它,如果替換必須在幾個輸入上完成。 –

+0

@SargeBorsch這是一個快速骯髒的例子。甚至有一個'Main'方法:-) – xanatos

0

如果您在談論單個字符串,解決方案是通過簡單的replace方法將其全部刪除。因爲您可以閱讀:

「返回一個新字符串,其中全部當前實例中指定字符串的出現被另一個指定字符串替換」。

你可能需要更換幾個單詞,並可以使這些單詞的列表:

List<string> wordsToRemove = new List<string>(); 
wordsToRemove.Add("why"); 
wordsToRemove.Add("how); 

,然後從字符串

foreach(string curr in wordsToRemove) 
    a = a.ToLower().Replace(curr, ""); 
刪除

Importent

if你要保持你的字符串,因爲它是,在不降低的話,並沒有與小寫和大寫使用掙扎

foreach(string curr in wordsToRemove) 
    // You can reuse this object 
    Regex regex = new Regex(curr, RegexOptions.IgnoreCase); 
    myString = regex.Replace(myString, ""); 
0

視情況而定ofcourse,
但如果你的文字很長,你有很多的話,
並且您希望優化性能。

你應該從單詞中建立一個trie,並搜索Trie進行匹配。

它不會降低複雜度的順序,仍然是O(nm),但對於大量的單詞,它將能夠針對每個字符而不是逐個字符來檢查多個單詞。
我可以假設幾個houndred單詞應該足以讓這個更快。

這是在我看來,最快速的方法和
我寫了一個功能,讓你下手:

public struct FindRecord 
    { 
     public int WordIndex; 
     public int PositionInString; 
    } 

    public static FindRecord[] FindAll(string input, string[] words) 
    { 
     LinkedList<FindRecord> result = new LinkedList<FindRecord>(); 
     int[] matchs = new int[words.Length]; 

     for (int i = 0; i < input.Length; i++) 
     { 
      for (int j = 0; j < words.Length; j++) 
      { 
       if (input[i] == words[j][matchs[j]]) 
       { 
        matchs[j]++; 
        if(matchs[j] == words[j].Length) 
        { 
         FindRecord findRecord = new FindRecord {WordIndex = j, PositionInString = i - matchs[j] + 1}; 
         result.AddLast(findRecord); 
         matchs[j] = 0; 
        } 

       } 
       else 
        matchs[j] = 0; 
      } 
     } 
     return result.ToArray(); 
    } 

另一種選擇:
這可能是罕見的情況下正則表達式會更快然後構建代碼。

嘗試使用

public static string ReplaceAll(string input, string[] words) 
    { 
     string wordlist = string.Join("|", words); 
     Regex rx = new Regex(wordlist, RegexOptions.Compiled); 
     return rx.Replace(input, m => ""); 
    } 
0

正則表達式可以做到這一點比較好,你只需要在列表中的所有替換單詞,然後:

var escapedStrings = yourReplaces.Select(PadAndEscape); 
string result = Regex.Replace(yourInput, string.Join("|", escapedStrings); 

這需要一個功能空間墊琴絃在轉義之前:

public string PadAndEscape(string s) 
{ 
    return Regex.Escape(" " + s + " "); 
} 
+0

這遭受「屁股」問題(http://www.codinghorror.com/blog/2008/10/obscenity-filters-bad-idea-or-incredibly-intercoursing -bad-idea.html)...'屁股'將取代CL **屁股** – xanatos

+0

@xanatos呃,固定。 –

相關問題