How to replace {vars} in a string?

7

I have a string

string str = "Bem vindo {Usuario}. Agora são: {Horas}";

I want to replace {Usuario} with a name and {Horas} with the current time, how can I do this?

    
asked by anonymous 19.12.2013 / 03:16

4 answers

6

One idea is to use IFormattable that understands its formats. For example, if you have a class like this:

class Modelo : IFormattable {
  public string Usuario { get; set; }
  public DateTime Horas { get { return DateTime.Now; } }
  public string ToString(string format, IFormatProvider formatProvider) {
    if (format == "Usuario") return Usuario;
    if (format == "Horas") return Horas.ToString();
    throw new NotSupportedException();
  }
}

You can use it this way:

var modelo = new Modelo { Usuario = "Lobo" };
var strFinal = string.Format("Bem vindo {0:Usuario}. Agora são: {0:Horas}", modelo);

Note that you still need to use the index of the object that will make the substitution (in this case, 0 ).

You can implement IFormattable by using reflection, for example, to override any property of the object.

    
19.12.2013 / 20:05
7

The OC # already has a function for this, if it is called String.Format see the documentation .

String.Format("Bem vindo {0}. Agora são: {1}", usuario, hora);

However if you want to implement something similar, you can use Regex as follows

var result = Regex.Replace(str, @"{(?<Parametro>[^}]+)}", m =>
{
    string variavel = m.Groups["Parametro"].Value; // Usuario, Horas
    switch (variavel)
    {
        case "Usuario": return usuario;
        case "Horas": return hora;
    }
    return "";
});

The (?<SomeName>.*) syntax means that this is a group Named, see the documentation here.

This allows you to access specific captured groups, via match.Groups["NomeDoGrupo"].Value .

This way you can capture tokens and replace them as you wish.

Although this is possible, I suggest using String.Format that was well thought out, validated, and is the default for this type of operation .

    
19.12.2013 / 03:16
6

As a complement to everything that has been answered in C # 6 there is a new string interpolation feature where, depending on the purpose, you can leave all this aside and leave the / > framework take care of this for you. Then using:

string str = $"Bem vindo {Usuario}. Agora são: {Horas}"

You will already get the desired result as long as at the time of evaluating the string you have the variables Usuario and Horas in the scope.

Read more about the subject .

    
10.12.2014 / 13:03
3

If your "{User}" key is fixed, it might be best to simply do a text replacement instead of using regular expressions. ERs are very cool and powerful, but there is a certain computational cost to be paid.

With a very simple test using the ER suggestion offered by @BrunoLM (which was a very good suggestion), you can see that the difference in processing time is quite considerable:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Text.RegularExpressions;

namespace ConsoleApplication2
{
    class Program
    {
        static string replace1(string str)
        {
            var result = Regex.Replace(str, @"{(?<Parametro>[^}]+)}", m =>
            {
                string variavel = m.Groups["Parametro"].Value; // Usuario, Horas
                switch (variavel)
                {
                    case "Usuario": return "Fulano da Silva";
                    case "Horas": return DateTime.Now.ToString("HH:mm:ss tt");
                }
                return "";
            });
            return result;
        }

        static string replace2(string str)
        {
            str = str.Replace("{Usuario}", "Beltrano da Silva");
            str = str.Replace("{Horas}", DateTime.Now.ToString("HH:mm:ss tt"));
            return str;
        }

        static void Main(string[] args)
        {

            string str = "Bem vindo {Usuario}. Agora são: {Horas}";

            DateTime dStart = DateTime.Now;
            Console.Out.WriteLine("Resultado 1: " + Program.replace1(str));
            DateTime dEnd = DateTime.Now;
            Console.Out.WriteLine("Duração: " + (dEnd - dStart).TotalMilliseconds);

            dStart = DateTime.Now;
            Console.Out.WriteLine("Resultado 2: " + Program.replace2(str));
            dEnd = DateTime.Now;
            Console.Out.WriteLine("Duração: " + (dEnd - dStart).TotalMilliseconds);
        }
    }
}

Produces the following output (duration in milliseconds):

Resultado 1: Bem vindo Fulano da Silva. Agora são: 15:28:15
Duração: 9,0005
Resultado 2: Bem vindo Beltrano da Silva. Agora são: 15:28:15
Duração: 1
    
19.12.2013 / 18:31