[Solved] How to replace tokens on a string template? [closed]


Short answer

I think it would be best to use a Regex.

var result = Regex.Replace(str, @"{{(?<Name>[^}]+)}}", m =>
{
    return m.Groups["Name"].Value; // Date, Time
});

On c#-6.0 you can use:

string result = $"Time: {DateTime.Now}";

String.Format & IFormattable

However, there is a method for that already. Documentation.

String.Format("The current Date is: {0}, the time is: {1}", date, time);

And also, you can use a class with IFormattable. I didn’t do performance tests but this one might be fast:

public class YourClass : IFormattable
{
    public string ToString(string format, IFormatProvider formatProvider)
    {
        if (format == "Date")
            return DateTime.Now.ToString("yyyy/MM/d");
        if (format == "Time")
            return DateTime.Now.ToString("HH:mm");
        if (format == "DateTime")
            return DateTime.Now.ToString(CultureInfo.InvariantCulture);

        return format;

        // or throw new NotSupportedException();
    }
}

And use as

String.Format("The current Date is: {0:Date}, the time is: {0:Time}", yourClass);

Review of your code and detailed information

In your current code you are using

// match.Value = {{Date}}
match.Value.Substring(2, match.Value.Length - 4).Replace(" ", String.Empty);

Instead, if you look at my code above, I used the pattern

@"{{(?<Name>[^}]+)}}"

The syntax (?<SomeName>.*) means this is a named group, you can check the documentation here.

It allows you to access match.Groups["SomeName"].Value which will be equivalent to the pattern with this group. So it would match two times, returning “Date” and then “Time”, so you don’t need to use SubString.

Updating your code, it would be

private const string RegexIncludeBrackets = @"{{(?<Param>.*?)}}";

public static string ParseString(string input)
{
    return Regex.Replace(input, RegexIncludeBrackets, match =>
    {
        string cleanedString = match.Groups["Param"].Value.Replace(" ", String.Empty);
        switch (cleanedString)
        {
            case "Date":
                return DateTime.Now.ToString("yyyy/MM/d");
            case "Time":
                return DateTime.Now.ToString("HH:mm");
            case "DateTime":
                return DateTime.Now.ToString(CultureInfo.InvariantCulture);
            default:
                return match.Value;
        }
    });
}

To improve even more, you can have a static compiled Regex field:

private static Regex RegexTemplate = new Regex(@"{{(?<Param>.*?)}}", RegexOptions.Compiled);

And then use as

RegexTemplate.Replace(str, match => ...);

2

solved How to replace tokens on a string template? [closed]