在 C#/.NET 中,格式化字串有兩種主要機制:使用 String.Format() 與字串內插。
String.Format() 會接受一個字串(在文件中稱為_複合格式_)以及數量不定的引數;該字串由固定文字與預留位置(在文件中稱為格式項目)組成。回傳值會使用對應的引數解析每個格式項目,再將解析後的值與固定文字結合。
string.Format("I had {0} bitcoins on {1}, the day I forgot my password.", 55.5, new DateTime(2010, 2, 25));
// => "I had 55.5 bitcoins on 2/25/2010 00:00:00, the day I forgot my password." - US settings
這個機制在技術上稱為_複合格式化_。
內插字串會以 $ 開頭,並包含以大括號括住的執行階段運算式。格式項目的語法如下:$"{<interpolationExpression>}"。它們省去了另外準備一份引數清單的需求。結果在功能上等同於 String.Format() 機制。
var loadsOf = 55.5;
var thatDay = new DateTime(2010, 2, 25);
$"I had {loadsOf} bitcoins on {thatDay}, the day I forgot my password."
// => "I had 55.5 bitcoins on 2/25/2010 00:00:00, the day I forgot my password." - US settings
大括號中的文字,在複合格式的情況是預留位置,在字串內插的情況則是內插運算式,稱為_格式項目_。
一個格式項目最多可由 3 個部分組成。第一個是必要的運算式或引數預留位置,如上面的範例程式碼所示。此外還有選用的對齊方式(以逗號「,」帶出)以及選用的_格式字串_(以冒號「:」帶出)。
{<interpolationExpression>[,<alignment>][:<formatString>]}
_對齊_會指定放置文字的「欄位」長度;對齊值為正時,會在左側以空格補齊,為負時則在右側補齊。
_格式字串_會指定文字輸出的形式,例如數字是否要包含千分位分隔符,或是否只輸出 DateTime 物件的日期部分。
以下程式碼示範如何顯示 DateTime 物件的日期部分,以及以指數形式顯示浮點數。
var loadsOf = 55.5;
var thatDay = new DateTime(2010, 2, 25);
$"I had {loadsOf:E} bitcoins on {thatDay:d}, the day I forgot my password."
// => I had 5.550000E+001 bitcoins on 02/25/2010, the day I forgot my password. - US settings
string.Format(
"I had {0:E} bitcoins on {1:d}, the day I forgot my password.",
loadsOf, thatDay)
// => I had 5.550000E+001 bitcoins on 02/25/2010, the day I forgot my password. - US settings
數字和日期都有標準格式與自訂格式。_自訂_與_標準_之間並沒有關鍵差異,唯一的差別是你有機會用格式字母自行組出格式字串。
每個執行緒都有一個預設的文化特性 Thread.CurrentThread.CurrentCulture,封裝在 CultureInfo 的執行個體中。執行緒的文化特性會決定日期與數字的格式化方式,並考量地區差異,例如英國慣用的日期格式 DD/MM/YYYY 與美國的 MM/DD/YYYY 之間的差異。
CultureInfo 會實作 IFormatProvider 介面,這個介面可以傳入 String.Format() 的某些多載。你可以用它來覆寫執行緒的文化特性。
逐字字串可以包含多行文字。它們以 @ 開頭。
string str = @"
See no wretched
quotes everywhere
";
在這個練習中,你要幫高中情侶在社群媒體上公開告白。
請實作靜態方法HighSchoolSweethearts.DisplaySingleLine(),接收兩個名字,並將它們以愛心分隔後顯示。
格式化後的字串寬度應為 61 個字元,並讓愛心位於字串正中央。
所有名字都保證能輕鬆容納在這行的寬度內。
HighSchoolSweethearts.DisplaySingleLine("Lance Green", "Pat Riley");
// => " Lance Green ♡ Pat Riley "
實作靜態方法HighSchoolSweethearts.DisplayBanner(),它會顯示兩組以加號分隔的姓名縮寫。
HighSchoolSweethearts.DisplayBanner("L. G.", "P. R.");
// see the ascii art below
****** ******
** ** ** **
** ** ** **
** * **
** **
** L. G. + P. R. **
** **
** **
** **
** **
** **
** **
***
*
實作靜態方法HighSchoolSweethearts.DisplayGermanExchangeStudents(),顯示我們德國交換學生的交往開始日期與交往時間長度。
HighSchoolSweethearts.DisplayGermanExchangeStudents("Norbert", "Heidi", new DateTime(2019, 1, 22), 1535.22f);
// => "Norbert and Heidi have been dating since 22.01.2019 - that's 1.535,22 hours"