How to perform c# regex multiple replacements
When you’re working with C# code, sometimes making individual changes just doesn’t make sense. You need your programming language to do it for you.
Luckily, c# can help make simple replacements. If you discover repeatable errors in a string, you can use c# Regex.Replace to swap out multiple values at once. Because Regex.Replace can read text, it’ll leave anything alone that doesn’t match the criteria you set, and your string will be fixed in no time.
C# regex replace multiple matches
Here’s an example:
Let’s say you’re testing the XML request for a web service and get this response:[400]: Error parsing xml.
After some troubleshooting, you discover the error was caused by thePredefined XML Entities in the data. The most common issue is the ampersand "&" being embedded in the address and account data. You need a way to replace those xml entity characters, but don’t want to update each one separately.
The Regex.Replace method has four overloads, but the basic syntax in .NET is Regex.Replace(string input, string pattern, string replacement). That won’t work because the replacement value could vary based on the pattern.
The pattern you’re looking for can include multiple items, but the replacement value is the same for each one. In that case, you need to use the overload that accepts aMatchEvaluator delegate each time a regular expression match is found during a Replace operation.
Regex.Replace(string input, string pattern, MatchEvaluator evaluator)
If the search and replace values are simple, you could use a generic dictionary and store the entity and its replacement as name value pairs.
var xmlEntityReplacements = new Dictionary<string, string> {
{ "&", "&" },
{ "'", "'" },
{ "<", "<" },
{ ">", ">" },
{ """, """ }
};
Then, revise the Regex like this:
Regex.Replace(input, "&|"|<|>|'", delegate(Match m) { return xmlEntityReplacements[m.Value]; })
Take it a step further with LINQ
That bears better results, but you could be duplicating items in the pattern if they are already in the dictionary. This is a perfect use case for a language-integrated query (LINQ).
First, return the dictionary keys to a pipe-delimited string. There is a CopyTo() method on the collection to convert the keys or values to an array, and from the array you’ll get the string you need. LINQ and its extension methods can also save you an extra step, so you don’t have to declare and array the values and then use CopyTo.
Regex.Replace(source, string.Join("|", xmlEntityReplacements.Keys
.Select(k => k.ToString()).ToArray()), m => xmlEntityReplacements[m.Value])
Here's the code converted to a method:
///<summary>
/// Replaces the 5 predefined entities in XML with the appropriate name /// escape character.
///</summary>
///<param name="source">string to search</param>
///<returns>source string with replaced value or original string</returns>
publicstaticstring ReplaceXmlEntity(string source)
{
if(string.IsNullOrEmpty(source)) return source;
// The XML specification defines five "predefined entities" representing
// special characters, and requires that all XML processors honor them.
var xmlEntityReplacements = new Dictionary<string, string> {
{ "&", "&" },
{ "'", "'" },
{ "<", "<" },
{ ">", ">" },
{ """, """ }
};
// Create an array and populate from the dictionary keys, then convert
// the array to a pipe-delimited string to serve as the regex search
// values and replace
return Regex.Replace(source, string.Join("|", xmlEntityReplacements.Keys
.Select(k => k.ToString()).ToArray()), m => xmlEntityReplacements[m.Value]);
}
Unfortunately, for more complex patterns and searches, the dictionary approach won't work. The MatchEvaluator expects to find the match as a key in the dictionary — and it won’t be there.
How Wipfli can help
Our technologists dive deep into the latest tools and strategies to keep your business moving forward. If you need help making your data work harder, contact us today. We’d love to share our experience and help you use data to thrive.
Related content: