C#實現類似"hello $world"的格式化字符串方法


   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         }
View Code

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         }
View Code

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM