How to replace curly braces and its contents in a string
I have run into an issue of trying to replace certain contents of a string delineated with curly braces with an outside value.
Relevant code example:
string value = "6";
string sentence = "What is 3 x {contents}";
# insert some sort of method sentence.replace(value,"{contents}");
What is the best method for replacing "{contents}" with value, given that the name inside the curly braces may change but whatever the name, it will be contained within the curly braces.
I looked a bit into regex and either the concepts were lost on me or I could not find relevant syntax to accomplish what I am trying to do. Is that the best way to accomplish this, and if so how? If not what would be a better method to accomplish this?
Solution 1:
Use Regex.Replace
:
string value = "6";
string sentence = "What is 3 x {contents}";
var result = Regex.Replace(sentence, "{.*?}", value); // What is 3 X 6
MSDN is a good place to start for understanding regex
Solution 2:
I usually end up doing something like this:
public static string FormatNamed(this string format, params object[] args)
{
var matches = Regex.Matches(format, "{.*?}");
if (matches == null || matches.Count < 1)
{
return format;
}
if (matches.Count != args.Length)
{
throw new FormatException($"The given {nameof(format)} does not match the number of {nameof(args)}.");
}
for (int i = 0; i < matches.Count; i++)
{
format = format.Replace(
matches[i].Value,
args[i].ToString()
);
}
return format;
}
Solution 3:
If I understand correctly what you want to do, and assuming you want to replace every instance of "{contents}" in your text, I see two solutions:
-
Using a simple
string.Replace(string, string)
:public static string InsertContent(string sentence, string placeholder, string value) { return sentence.Replace("{" + placeholder + "}", value); }
Note that the function returns a new string object.
-
If you want to replace anything between brackets by a given value, or just have no control on what the string between brackets will be, you can also use a
Regex
:public static string InsertContent(string sentence, string value) { Regex rgx = new Regex(@"\{[^\}]*\}"); return rgx.Replace(sentence, value); }
Again, the function returns a new string object.
Solution 4:
This answer is just like @WizxX20's, but this V2 method has slightly more intuitive behavior and more efficient string replacing logic which would become apparent if running this method against a large text file. Judge for yourself:
string someStr = "I think I had {numCows} cows, wait actually it was {numCows} when I heard that serendipitous news at {time}.";
object[] args = new object[] { 3, 5, "13:45"};
//I think I had 3 cows, wait actually it was 3 when I heard that serendipitous news at 13:45.
Console.WriteLine(FormatNamed(someStr, args));
//"I think I had 3 cows, wait actually it was 5 when I heard that serendipitous news at 13:45."
Console.WriteLine(FormatNamedV2(someStr, args));
static string FormatNamedV2(string format, params object[] args)
{
if(string.IsNullOrWhiteSpace(format))
return format;
var i = 0;
var sanitized = new Regex("{.*?}").Replace(format, m =>
{
//convert "NumTimes: {numTimes}, Date: {date}" to "NumTimes: {0}, Date: {1}" etc.
var replacement = $"{{{i}}}";
i++;
return replacement;
});
if (i != args?.Length)
{
var formatPrettyPrint = format.Length > 16 ? $"{format.Substring(0, 16)}..." : format;
throw new FormatException($"The given {nameof(format)} \"{formatPrettyPrint}\" does not match the number of {nameof(args)}: {args.Length}.");
}
return string.Format(sanitized, args);
}