Multiple string replacement (with similarity) using a dictionary I'm trying to replace a number of keywords with other corresponding values. I started with this method:

Dictionary&lt;string, string&gt; keywords = GetKeywords();
foreach (var pair in keywords)
{
    var re = new Regex($@"\b{pair.Key}\b");
    if (re.IsMatch(text))
        text = re.Replace(text, pair.Value);
}


..which becomes slower and slower when the number of keywords increases. So, I used a different method (by only scanning the string once and checking each word against the dictionary):

text =
    Regex.Replace(text, @"\w+", delegate (Match m)
    {
        string word = m.Value;
        string value;
        if (keywords.TryGetValue(word, out value))
            return value;
        else
            return word;
    });


..which worked great for the original requirement. However, I was forced to switch back to the first method because I need to match/replace keywords that are not 100% equal to what's in the dictionary. For example, in the first method, I would do something like this:

string keyword = pair.Key.Replace("e", "[eé]")
var re = new Regex($@"\b{keyword}\b");


Is there a way around this using the second method? Or any other methods faster than the first one?

Notes:


It's not just accented letters, so something like IgnoreNonSpace will not work.
Both regex patterns are a little bit more complicated, that is, they both have a negative lookahead ((?![^&lt;]*&gt;|[^&amp;]*;)) but I don't think that affects the outcome as the pattern is essentially just matching single words.


The only solution I could think of is to "normalize" the keywords before adding them to the dictionary (e.g., replace "[eé]" with "e") and then "normalize" each word before passing it to TryGetValue() but I'd like to see if there's a better solution first because this one will be a little bit messy.
I can be wrong, but it seems that the problem is that if you have a large number of keywords, you are defining a lot of regular expressions in vain. How about creating a single regex and replacing values only for found keywords?

var words = string.Join("|", keywords.Keys);
text = Regex.Replace(text, $@"\b({words})\b", delegate (Match m)
{
    return keywords[m.Value];
});