在不影响将来替换的情况下查找并替换几个单词
本文关键字:替换 单词 几个 查找 影响 将来 情况下 | 更新日期: 2023-09-27 17:59:49
我想做的是突出显示某种"禁止使用的单词"。
以下是我的值:
我有一个数组中的禁止字列表
{ "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"
我不想影响我的替代者。我想知道我们该怎么做。我尝试在regex中添加异常以排除替换中的<b>
和</b>
,但没有成功。
忽略问题的整个"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);
在一般情况下,这里需要的是替换输入中的一些术语,而不是迄今为止生成的输出中的一些。这并不难手动完成,但首先你必须确定哪个术语优先被替换。
假设你有一本术语和替换词的词典,选择替换哪个术语的策略是"替换最接近输入开头的术语;如果多个术语出现在同一位置,则替换最长的术语"。这里有一种方法:
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();
}
在实际操作中查看。
当然,这并不是你想要在这里做的(事实上,用一个正则表达式同时替换所有内容可能是最方便的),但你可以看到它是如何工作的。