Для тех, кто заинтересован, вот мое окончательное решение. Это для пользовательского контроля .NET. Он использует один шаблон с оценщиком совпадений, как предлагает Томалак, поэтому цикл foreach отсутствует. Это элегантное решение, и оно дает мне правильный вывод для ввода сэмпла, сохраняя при этом правильный регистр для согласованных строк.
public partial class Abbreviations : System.Web.UI.UserControl
{
private Dictionary<String, String> dictionary = DataHelper.GetAbbreviations();
protected void Page_Load(object sender, EventArgs e)
{
string input = "This is just a little test of the memb. And another memb, but not amemba to see if it gets picked up. Deb of course should also be caught here.deb!";
var regex = "\\b(?:" + String.Join("|", dictionary.Keys.ToArray()) + ")\\b";
MatchEvaluator myEvaluator = new MatchEvaluator(GetExplanationMarkup);
input = Regex.Replace(input, regex, myEvaluator, RegexOptions.IgnoreCase);
litContent.Text = input;
}
private string GetExplanationMarkup(Match m)
{
return string.Format("<b title='{0}'>{1}</b>", dictionary[m.Value.ToLower()], m.Value);
}
}
Вывод выглядит следующим образом (ниже). Обратите внимание, что он соответствует только полным словам, и что регистр сохраняется из исходной строки:
This is just a little test of the <b title='Member'>memb</b>. And another <b title='Member'>memb</b>, but not amemba to see if it gets picked up. <b title='Debut'>Deb</b> of course should also be caught here.<b title='Debut'>deb</b>!