2013-02-18 27 views
4

我想要做的是某種「禁止的詞」突出顯示。查找並替換幾個詞而不影響將來的替換

這裏是價值觀,我有:

我有一個數組bannedwords列表

{ "word1", "word2", "word3", "word4" } 

我代表評論

"i want to word1ban this word3 stupidword4 comment" 

我想強調這些字符串在HTML粗體標籤內(<b> </b>)。 因此,例如,該註釋字符串將成爲:

"i want to <b>word1</b>ban this <b>word3</b> stupid<b>word4</b> comment" 

我這樣做實際上的方式,是使用正則表達式替換,它工作得很好,除了一兩件事很討厭我。

foreach (var word in words) 
{ 
    value = Regex.Replace(value, string.Format(@"{0}", Regex.Escape(HttpUtility.HtmlEncode(word))), "<b>" + word + "</b>", RegexOptions.IgnoreCase); 
} 

與此問題,而且它也取決於陣列中字的順序,是如果被禁止的話人會影響你的更換(<b></b>

例如,如果您添加到禁止的字詞:<b

繼碼,第一次迭代的結果將是:

"i want to <b>word1</b>ban this <b>word3</b> stupid<b>word4</b> comment" 

然後用<b代替之後:

"i want to <b><b</b>>word1</b>ban this <b><b</b>>word3</b> stupid<b><b</b>>word4</b> comment" 

我不想影響我的更換。我想知道我們如何做到這一點。我嘗試在我的正則表達式中添加例外,以便在替換中排除<b></b>,但沒有成功。

+0

您的替代品對HTML沒有任何意義,它只是替換您告訴它的內容。它無法區分標籤內的文本和文本。您需要更明確地使用替換正則表達式,或者使用可以解析HTML的HTML Agility Pack之類的東西。 – Lloyd 2013-02-18 14:56:09

+0

看看這裏:http://stackoverflow.com/questions/653700/highlight-a-list-of-words-using-a-regular-expression-in-c-sharp – Najzero 2013-02-18 14:56:18

+0

你總是可以使用正則表達式的元素解析HTML並避免以這種方式破壞標籤。 – Stonehead 2013-02-18 14:58:31

回答

2

忽略了問題的整個「HTML」方面,只是在它的到來,從

我想查找和替換幾個單詞的角度,但我不想更換我已經使影響將來的替代品

你可以做一件事:一次做所有的替換!

var pattern = "(" + String.Join("|", words.Select(w => Regex.Escape(w))) + ")"; 
// e.g. (word1|word2|word3|word4) 
value = Regex.Replace(
    value, 
    pattern, 
    "<b>$1</b>", 
    RegexOptions.IgnoreCase); 
+0

是的,我想要一個解決方案,就像你說的那樣,「忽略」HTML方面,這只是針對問題的上下文。非常感謝,這正是我所期待的,而且效果非常好! – mhoude 2013-02-25 16:49:43

0

在一般情況下,您在此需要的是替換輸入中的一些術語,而不是在迄今爲止產生的輸出中。手動操作並不難,但首先您必須確定哪個術語優先被替換。

假設您有詞典和替換詞典,並且選擇要替換的詞語的策略是「替換與輸入開頭最接近的詞語;如果許多詞語出現在相同的位置,則替換最長的一個「。下面是其中一種做法:

string ReplaceWithoutOverlap(string input, IDictionary<string, string> replacements) 
{ 
    var processedCharCount = 0; 
    var sb = new StringBuilder(); 
    while (processedCharCount < input.Length) { 
     var replacement = replacements 
       .Select(r => Tuple.Create(r.Key, input.IndexOf(r.Key, processedCharCount))) 
       .Where(t => t.Item2 != -1) 
       .OrderBy(t => t.Item2) 
       .ThenByDescending(t => t.Item1.Length) 
       .FirstOrDefault(); 

     if (replacement == null) 
     { 
      break; 
     } 

     sb.Append(input, processedCharCount, replacement.Item2 - processedCharCount); 
     sb.Append(replacements[replacement.Item1]); 
     processedCharCount = replacement.Item2 + replacement.Item1.Length; 
    } 

    sb.Append(input.Substring(processedCharCount)); 
    return sb.ToString(); 
} 

See it in action

當然這不是正好你想在這裏做什麼(實際上用一個正則表達式替換一切可能是最方便的),但你可以看到它是如何工作的。