C#自帶的string.Format可以格式化字符串,但是還是不太好用,由於格式的字符占位符都是數字,當數目較多時容易混淆。其實可以擴展string的方法,讓C#的字符串具備其他的方法,下面介紹一個實現類似String.jQueryStringFormat("hello $world", new {world="cnblog" })的擴展方法。
1 變量前綴$
可以仿照jQuery中的選擇器方法,用$作為變量前綴。例如 I love \$something 中的$someting就是變量,可以將something變量的值替換到字符串中。
1 //模板字符串前綴 2 private static readonly string __prefix = "$"; 3 // $ 正則表達式 $name 4 private static readonly Regex VariableRegex = new Regex(@"\$(@{0,1}[a-zA-Z_\.0-9]+)"); 5
2 正則表達式捕獲變量
上面定義了變量的規則,必須是$打頭的有效變量,下面將字符串用該正則表達式進行捕獲
1 private static IEnumerable<string> GetEnumerateVariables(string s) 2 { 3 var matchCollection = VariableRegex.Matches(s); 4 5 for (int i = 0; i < matchCollection.Count; i++) 6 { 7 yield return matchCollection[i].Groups[1].Value; 8 } 9 }
3 用反射獲取對象屬性的值
傳入的對象含有各個屬性,寫一個方法獲取指定屬性的值

1 /// <summary> 2 /// 獲取對象的對應屬性值 3 /// </summary> 4 /// <param name="oValue">包含值的對象</param> 5 /// <param name="name">屬性名</param> 6 /// <returns></returns> 7 private static object ValueForName(object oValue, string name) 8 { 9 Type type = oValue.GetType(); 10 var property = type.GetProperty(name); 11 if (property != null) 12 { 13 return property.GetValue(oValue, new object[0]); 14 } 15 16 var field = type.GetField(name); 17 if (field != null) 18 { 19 return field.GetValue(oValue); 20 } 21 throw new FormatException("未找到命名參數: " + name); 22 }
4 String方法擴展

1 public static string jQueryStringFormat(this String @this, string sjQueryStringT, object oValue) 2 { 3 4 //檢測驗證 5 if (string.IsNullOrEmpty(sjQueryStringT)) 6 return sjQueryStringT; 7 if (!sjQueryStringT.Contains(__prefix)) 8 throw new Exception("字符串中變量不包含$前綴"); 9 if (oValue == null) 10 return sjQueryStringT; 11 12 //解析 13 //need using System.Linq; 14 var variables = GetEnumerateVariables(sjQueryStringT).ToArray(); 15 foreach (string vname in variables) 16 { 17 //獲取值 18 string vvalue = ValueForName(oValue, vname).ToString(); 19 //字符串替換 20 sjQueryStringT = sjQueryStringT.Replace("$" + vname, vvalue); 21 22 23 } 24 return sjQueryStringT; 25 }
5 單元測試
其實在VS2012中可以自動生成單元測試代碼,然后稍加改動就可以對編寫的方法進行單元測試,非常方便
1 /// <summary> 2 ///jQueryStringFormat 的測試 3 ///</summary> 4 [TestMethod()] 5 public void jQueryStringFormatTest() 6 { 7 string @this = ""; // TODO: 初始化為適當的值 8 9 string Name = "JackWang"; 10 int ID = 100; 11 string sjQueryStringT = "exec func($Name,$$ID)"; // TODO: 初始化為適當的值 12 object oValue = new { ID, Name }; // TODO: 初始化為適當的值 13 string expected = "exec func(JackWang,$100)"; // TODO: 初始化為適當的值 14 string actual; 15 actual = StringFormat.jQueryStringFormat(@this, sjQueryStringT, oValue); 16 Assert.AreEqual(expected, actual); 17 //Assert.Inconclusive("驗證此測試方法的正確性。"); 18 }
6 應用示范
1 string Name = "jack"; 2 int ID = 200; 3 string template = "exec func($Name,$ID)"; 4 string parseText = template.jQueryStringFormat(template, new { ID, Name }); 5
也可以傳入一個類的實例
1 template = "the $Name who ID is $$ID"; 2 parseText = template.jQueryStringFormat(template, new Person { ID = "2", Name = "JackWang" });
7 GitHub開源
項目源碼放於GitHub中https://github.com/JackWangCUMT/jQueryStringFormat