替换给定字符串中的变量

Replace variables from a given string

我有一个带有变量名称的字符串,格式类似于插值。

Class MailManager{
    CreateMail(){
        Mail mail = new Mail("This is the mail {name}")
    }
    class Mail{
        string header {get;set;}
        string name {get;set;}

        internal Mail(string header){
            this.header = header;
            name = "i am the mail name";
        }
        internal void FormatHeader(){
            //Do something here to evaluate variables in header
        }
    }
}

我想用变量值替换{name}和其他变量名。

我尝试使用 SmartFormat

 void FormatHeader(){
     header =  Smart.Format(header)
 }

但是它抛出一个错误Could not evaluate the selector "name"

我试过反思:

 void FormatHeader(){
      foreach (Match m in Regex.Matches(header, @"{(.*?)}"))
      {
           header = header.Substring(0,m.Index) +  GetType().GetProperty(m.Groups[1].ToString()) + header.Substring(m.Index + m.Length);
      }
 }

但是这里GetType().GetProperty("name")没有找到任何东西

有没有办法更正此解决方案之一?要不然再找一个?

除非我遗漏了什么,你可以简单地使用 Replace:

var sourceString = "This is the mail {name}";
var targetString = sourceString.Replace("{name}", name);

好像太复杂了,就用String.Replace方法

这是文档的 link: https://docs.microsoft.com/en-us/dotnet/api/system.string.replace?view=net-5.0

GetType().GetProperty() 仅 returns public 属性,使您的 属性 public 正常工作(或者您可以使用 bindingFlags)

看看这个: https://docs.microsoft.com/en-us/dotnet/api/system.type.getproperty?view=net-5.0

如果您正在寻找详细的解决方案,您可以尝试 反射 正则表达式:

  using System.Linq;
  using System.Reflection;
  using System.Text;
  using System.Text.RegularExpressions;

  ...

  internal void FormatHeader() {
    // Get all readable (non-indexer) properties' names and values
    Dictionary<string, object> data = GetType()
      .GetProperties(BindingFlags.Instance | BindingFlags.Static |
                     BindingFlags.Public | BindingFlags.NonPublic)
      .Where(p => p.CanRead && p.GetIndexParameters().Length <= 0)
      .ToDictionary(
         p => p.Name, 
         p => p.GetValue((p.GetAccessors(true)[0].IsStatic ? null : this), 
                          Array.Empty<object>()));

    // Replace all {name} fragments to corresponing values
    header = Regex.Replace(
      header,
      @"\{\s*\p{L}[\p{L}_0-9]*\s*\}",
      m => data.TryGetValue(m.Value.Trim('{', '}', ' '), out var v) 
              ? v?.ToString() 
              : m.Value);
  }