8

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?

Zannith
  • 105
  • 1
  • 1
  • 5

5 Answers5

6

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

Gilad Green
  • 36,708
  • 7
  • 61
  • 95
  • Thank you, in this case what exactly is the .* doing? i get it has something to do with adding the contents but what does each item individually accomplish – Zannith Oct 04 '16 at 14:08
  • 5
    @Zannith: Now would be a good time to read a primer on regular expressions, rather than asking individually about each little part. – Jon Skeet Oct 04 '16 at 14:09
  • The regex is wrong, try to replace "Example {text1} more text {text2}" with it. – enkryptor Oct 04 '16 at 14:09
  • @Jon Skeet: yes i looked for information on it earlier but all i found was some really confusing stuff for a beginner like me. Do you have an idea on a good place for me to study up on? – Zannith Oct 04 '16 at 14:12
  • @Zannith - Added a link to some explanation – Gilad Green Oct 04 '16 at 14:12
3

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;
        }
WizxX20
  • 311
  • 2
  • 6
1

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:

  1. 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.

  2. 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.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
1

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);
}
    
Michael Socha
  • 1,748
  • 1
  • 16
  • 17
0

You can use this code:

Regex.Replace(input, @"{[^{}]+}", "new string");
Thomas Ayoub
  • 29,063
  • 15
  • 95
  • 142