C# 将字符串中变量的名称替换为该变量的值
将嵌入到指定字符串中的每个变量的名称替换为该变量的值的等效字符串,然后返回结果字符串。
指定字符串中可以包含零个或多个变量名的字符串。每个变量都用百分号 (%) 引起来。
类似函数 System.Environment.ExpandEnvironmentVariables 。
使用示例(测试函数): System.PercentVariableStringFormat.Test() 。
namespace System
{
using System.Collections.Generic;
using System.Text.RegularExpressions;
/// <summary>
/// <para>将嵌入到指定字符串中的每个变量的名称替换为该变量的值的等效字符串,然后返回结果字符串。</para>
/// <para>指定字符串中可以包含零个或多个变量名的字符串。每个变量都用百分号 (%) 引起来。</para>
/// <para>类似函数 <see cref="System.Environment.ExpandEnvironmentVariables"/>。</para>
/// <para>使用示例(测试函数): <see cref="System.PercentVariableStringFormat.Test"/> 。</para>
/// </summary>
public class PercentVariableStringFormat
{
/// <summary>
/// 使用示例(测试函数)。
/// </summary>
[System.Diagnostics.Conditional("DEBUG")]
public static void Test()
{
var dic = new Dictionary<string, string>(12);
dic["Name"] = "Tom";
dic["Behavior"] = "running";
var stringFormat = new PercentVariableStringFormat(dic);
var formatString = "%Name% likes %Behavior%";
var newString = stringFormat.Format(formatString);
System.Diagnostics.Debug.Assert(newString == "Tom likes running", "PercentVariableStringFormat error");
}
private const char LeftFormat = '%';
private const char RightFormat = '%';
private const int LeftFormatLength = 1;
private const int RightFormatLength = 1;
private const string RegexPattern = @"%[a-zA-Z_-][a-zA-Z0-9()_-]*%";
private readonly ICollection<IDictionary<string, string>> variableDicCollection;
public PercentVariableStringFormat(ICollection<IDictionary<string, string>> variableDicCollection)
{
this.variableDicCollection = variableDicCollection;
}
public PercentVariableStringFormat(IDictionary<string, string> variableDic)
: this(new IDictionary<string, string>[] { variableDic })
{
}
/// <summary>
/// 将嵌入到指定字符串中的每个环境变量的名称替换为该变量的值的等效字符串,然后返回结果字符串。
/// <para>类似函数 <see cref="System.Environment.ExpandEnvironmentVariables"/>。</para>
/// </summary>
/// <param name="format">指定字符串中可以包含零个或多个变量名的字符串。每个变量都用百分号 (%) 引起来。</param>
/// <returns></returns>
public virtual string Format(string format)
{
string result;
if (string.IsNullOrEmpty(format))
{
result = format;
}
else if (HasFormatChar(format))
{
try
{
var replaceRegex = new Regex(RegexPattern);
result = replaceRegex.Replace(format, MatchEvaluator);
}
catch (Exception ex)
{
TraceException($"Format percent variable string '{format}' exception: ", ex);
result = format;
}
}
else
{
result = format;
}
return result;
}
private string MatchEvaluator(Match match)
{
string variableName = GetVariableName(match.Value);
string variableValue;
if (!TryGetVariable(variableName, out variableValue))
{
variableValue = match.Value;
}
return variableValue;
}
/// <summary>
/// 根据变量的名称,获取该变量的值。
/// </summary>
/// <param name="name">变量的名称。不包含百分号 (%) 。</param>
/// <param name="value">变量的值。</param>
/// <returns></returns>
public bool TryGetVariable(string name, out string value)
{
bool isFind = false;
value = null;
if (name != null && variableDicCollection != null && variableDicCollection.Count > 0)
{
foreach (var variableDic in variableDicCollection)
{
isFind = variableDic != null && variableDic.TryGetValue(name, out value);
if (isFind)
{
break;
}
}
}
return isFind;
}
private static string GetVariableName(string matchValue)
{
string variableName = string.Empty;
var totalFormatLength = LeftFormatLength + RightFormatLength;
if (matchValue.Length > totalFormatLength)
{
variableName = matchValue.Substring(LeftFormatLength, matchValue.Length - totalFormatLength);
}
return variableName;
}
private static bool HasFormatChar(string format)
{
var hasFormatChar = false;
var index1 = format.IndexOf(LeftFormat) + 1;
if (index1 >= 1 && index1 < format.Length)
{
var index2 = format.IndexOf(RightFormat, index1);
hasFormatChar = index2 >= 0;
}
return hasFormatChar;
}
private static void TraceException(string message, Exception ex)
{
System.Diagnostics.Trace.Write(message);
System.Diagnostics.Trace.WriteLine(ex);
}
}
}