複合書式設定
.NET Framework の複合書式指定機能は、オブジェクトのリストおよび複合書式指定文字列を入力として使用します。 複合書式指定文字列は、固定テキストに、書式指定項目と呼ばれるインデックス化されたプレースホルダーが混合されて構成されます。このプレースホルダーはリスト内のオブジェクトに対応します。 書式設定操作によって生成される結果の文字列は、元の固定テキストに文字列で表されたリスト内のオブジェクトが混合されて構成されます。
複合書式指定機能をサポートするメソッドには、Format、AppendFormat、および WriteLine と TextWriter.WriteLine のいくつかのオーバーロードなどがあります。 String.Format メソッドは書式設定された結果文字列を生成し、AppendFormat メソッドは書式設定された文字列を StringBuilder オブジェクトに追加します、また、Console.WriteLine メソッドは書式設定された結果文字列をコンソールに出力し、TextWriter.WriteLine メソッドは書式設定された結果文字列をストリームまたはファイルに書き込みます。
複合書式指定文字列
複合書式指定文字列とオブジェクト リストは、複合書式指定機能をサポートするメソッドの引数として使用されます。 複合書式指定文字列は、1 つ以上の書式指定項目が混合された 0 個以上の固定テキストで構成されます。 固定テキストはユーザーが任意に選択した文字列で、各書式指定項目はリスト内のオブジェクトまたはボックス化された構造体に対応します。 複合書式指定機能は、各書式指定項目がリスト内の対応するオブジェクトの文字列表現で置換された新しい文字列を返します。
次の Format コードがあるとします。
Dim myName As String = "Fred"
String.Format("Name = {0}, hours = {1:hh}", myName, DateTime.Now)
string myName = "Fred";
String.Format("Name = {0}, hours = {1:hh}", myName, DateTime.Now);
固定テキストは、"Name = " および ", hours = " です。 書式指定項目の 1 つは、インデックスが 0 である "{0}" で、 myName オブジェクトに対応します。もう 1 つはインデックスが 1 である "{1:hh}" で、 DateTime.Now オブジェクトに対応します。
書式指定項目の構文
各書式指定項目は、次の形式を使用し、次のコンポーネントで構成されます。
{index[,alignment][:formatString]}
対になった中かっこ ("{" と "}") が必要です。
Index コンポーネント
必須の index コンポーネントは、パラメーター指定子とも呼ばれ、オブジェクトのリスト内で対応する項目を識別するための 0 から始まる数値です。 つまり、パラメーター指定子が 0 である書式指定項目はリスト内の最初のオブジェクトを書式設定し、パラメーター指定子が 1 である書式指定項目はリスト内の 2 番目のオブジェクトを書式設定します。
同じパラメーター指定子を指定することによって、複数の書式指定項目でオブジェクトのリスト内の同じ要素を参照できます。 たとえば、複合書式指定文字列で "{0:X} {0:E} {0:N}" のように指定することによって、1 つの数値を 16 進形式、指数形式、および数値形式で書式設定できます。
各書式指定項目は、リスト内のどのオブジェクトでも参照できます。 たとえば、3 つのオブジェクトが存在する場合、2 番目、1 番目、3 番目のオブジェクトを書式設定するには、"{1} {0} {2}" のような複合書式指定文字列を指定します。 書式指定項目で参照されないオブジェクトは無視されます。 パラメーター指定子がオブジェクトのリストの範囲外の項目を指定する場合は、ランタイム例外が発生します。
Alignment コンポーネント
省略可能な alignment コンポーネントは、書式設定フィールドの幅を指定する符号付き整数です。 alignment の値が書式設定する文字列の長さよりも小さい場合、alignment は無視され、書式設定する文字列の長さがフィールドの幅として使用されます。 フィールド内の書式設定されたデータは、alignment が正の場合は右揃え、alignment が負の場合は左揃えされます。 埋め込みが必要な場合は、空白が使用されます。 alignment を指定する場合はコンマが必要です。
Format String コンポーネント
オプションの formatString コンポーネントは、書式設定されるオブジェクトの種類に適した書式指定文字列です。 対応するオブジェクトが数値の場合は標準またはカスタムの数値書式指定文字列を指定し、対応するオブジェクトが DateTime オブジェクトの場合は標準またはカスタムの日時書式指定文字列を指定し、対応するオブジェクトが列挙値の場合は列挙型書式指定文字列を指定します。 formatString が指定されない場合は、数値、日付と時刻、または列挙型の汎用 ("G") 書式指定子が使用されます。 formatString を指定する場合はコロンが必要です。
![]() |
---|
標準およびカスタムの数値書式指定文字列の一覧については、「標準の数値書式指定文字列」および「カスタム数値書式指定文字列」を参照してください。標準の日時書式指定文字列の一覧については、「標準の日付と時刻の書式指定文字列」および「カスタムの日付と時刻の書式指定文字列」を参照してください。 |
エスケープ中かっこ ({})
左中かっこ ({) および右中かっこ (}) は、書式指定項目の開始および終了として解釈されます。 したがって、左中かっこおよび右中かっこを文字として表示するためには、エスケープ シーケンスを使用する必要があります。 左中かっこを 1 つ ("{") 表示するには、左中かっこ 2 つ ("{{") を固定テキストに指定します。また、右中かっこを 1 つ ("}") 表示するには、右中かっこ 2 つ ("}}") を指定します。 書式指定項目に使用されている中かっこは、指定されている順序に従って解釈されます。 入れ子になった中かっこを解釈する機能はサポートされていません。
エスケープされた中かっこの解釈によっては、予測しない結果になる場合があります。 たとえば、"{{{0:D}}}" という書式指定項目について考えます。この書式指定項目は、左中かっこ、10 進数として書式設定された数値、および右中かっこを表示することを意図しています。 しかし、この書式指定項目は、実際には、次のように解釈されます。
最初の 2 つの左中かっこ ("{{") がエスケープされ、左中かっこ 1 つが作成されます。
次の 3 文字 ("{0:") は、書式指定項目の開始として解釈されます。
次の文字 ("D") は、Decimal 標準数値書式指定子として解釈できますが、エスケープされた次の 2 つの右中かっこ ("}}") からは単一の中かっこが作成されます。 結果として作成される文字列 ("D}") は、標準数値書式指定子ではないため、リテラル文字列 "D}" の表示を意味するカスタム書式指定文字列として解釈されます。
最後の中かっこ ("}") は、書式指定項目の終わりとして解釈されます。
最終的には、"{D}" というリテラル文字列が表示されます。 書式設定対象だった数値は、表示されません。
エスケープした中かっこと書式指定項目とが誤って解釈されないコードを記述するためには、中かっこと書式指定項目を別々に書式設定するという方法があります。 つまり、最初の書式設定操作でリテラルの開く中かっこを表示し、次の書式設定操作で書式指定項目の結果を表示し、最後の操作でリテラルの閉じる中かっこを表示します。 このアプローチの例を次に示します。
Dim value As Integer = 6324
Dim output As String = String.Format("{0}{1:D}{2}", _
"{", value, "}")
Console.WriteLine(output)
' The example displays the following output:
' {6324}
int value = 6324;
string output = string.Format("{0}{1:D}{2}",
"{", value, "}");
Console.WriteLine(output);
// The example displays the following output:
// {6324}
処理の順序
書式指定項目に対応するパラメーター リストのそれぞれの値は、次の一覧の手順を実行することで文字列に変換されます。 最初の 3 つの手順の条件のいずれかに該当する場合は、その手順で値の文字列形式が返され、後続の手順は実行されません。
書式設定する値が null の場合は、空の文字列 ("") が返されます。
複合書式指定メソッドに、ICustomFormatter インターフェイスも実装する IFormatProvider 型のパラメーターが含まれる場合は、値が ICustomFormatter.Format メソッドに渡されます。
値が IFormattable インターフェイスを実装している場合は、その IFormattable.ToString メソッドが呼び出されます。
Object クラスからオーバーライドまたは継承された、その型の ToString メソッドが呼び出されます。
前の手順が実行された後、調整が適用されます。
コード例
複合書式指定を使用して文字列を作成する方法と、オブジェクトの ToString メソッドを使用して文字列を作成する方法を示すコード例を次に示します。 この 2 つの書式設定方法では、等価の文字列が作成されます。
Dim FormatString1 As String = String.Format("{0:dddd MMMM}", DateTime.Now)
Dim FormatString2 As String = DateTime.Now.ToString("dddd MMMM")
string FormatString1 = String.Format("{0:dddd MMMM}", DateTime.Now);
string FormatString2 = DateTime.Now.ToString("dddd MMMM");
現在の曜日が木曜日であり、月が 5 月であり、現在のカルチャが英語 (U.S.) の場合、上記のコード例で作成される 2 つの文字列はどちらも Thursday May です 。
Console.WriteLine は、String.Format と同じ機能を公開します。 これら 2 つのメソッドの唯一の違いは、String.Format が結果を文字列で返すのに対し、Console.WriteLine は、Console オブジェクトに関連付けられた出力ストリームに結果を書き出す点です。 Console.WriteLine メソッドを使用して値 MyInt を通貨値として書式設定するコード例を次に示します。
Dim MyInt As Integer = 100
Console.WriteLine("{0:C}", MyInt)
' The example displays the following output
' if en-US is the current culture:
' $100.00
int MyInt = 100;
Console.WriteLine("{0:C}", MyInt);
// The example displays the following output
// if en-US is the current culture:
// $100.00
1 つのオブジェクトを 2 つの方法で書式設定する例を含め、複数のオブジェクトを書式設定する例を次に示します。
Dim myName As String = "Fred"
Console.WriteLine(String.Format("Name = {0}, hours = {1:hh}, minutes = {1:mm}", _
myName, DateTime.Now))
' Depending on the current time, the example displays output like the following:
' Name = Fred, hours = 11, minutes = 30
string myName = "Fred";
Console.WriteLine(String.Format("Name = {0}, hours = {1:hh}, minutes = {1:mm}",
myName, DateTime.Now));
// Depending on the current time, the example displays output like the following:
// Name = Fred, hours = 11, minutes = 30
書式設定で調整を使用する方法を示す例を次に示します。 調整結果を強調表示するため、書式が設定される引数を縦棒 (|) で囲んでいます。
Dim myFName As String = "Fred"
Dim myLName As String = "Opals"
Dim myInt As Integer = 100
Dim FormatFName As String = String.Format("First Name = |{0,10}|", myFName)
Dim FormatLName As String = String.Format("Last Name = |{0,10}|", myLName)
Dim FormatPrice As String = String.Format("Price = |{0,10:C}|", myInt)
Console.WriteLine(FormatFName)
Console.WriteLine(FormatLName)
Console.WriteLine(FormatPrice)
Console.WriteLine()
FormatFName = String.Format("First Name = |{0,-10}|", myFName)
FormatLName = String.Format("Last Name = |{0,-10}|", myLName)
FormatPrice = String.Format("Price = |{0,-10:C}|", myInt)
Console.WriteLine(FormatFName)
Console.WriteLine(FormatLName)
Console.WriteLine(FormatPrice)
' The example displays the following output on a system whose current
' culture is en-US:
' First Name = | Fred|
' Last Name = | Opals|
' Price = | $100.00|
'
' First Name = |Fred |
' Last Name = |Opals |
' Price = |$100.00 |
string myFName = "Fred";
string myLName = "Opals";
int myInt = 100;
string FormatFName = String.Format("First Name = |{0,10}|", myFName);
string FormatLName = String.Format("Last Name = |{0,10}|", myLName);
string FormatPrice = String.Format("Price = |{0,10:C}|", myInt);
Console.WriteLine(FormatFName);
Console.WriteLine(FormatLName);
Console.WriteLine(FormatPrice);
Console.WriteLine();
FormatFName = String.Format("First Name = |{0,-10}|", myFName);
FormatLName = String.Format("Last Name = |{0,-10}|", myLName);
FormatPrice = String.Format("Price = |{0,-10:C}|", myInt);
Console.WriteLine(FormatFName);
Console.WriteLine(FormatLName);
Console.WriteLine(FormatPrice);
// The example displays the following output on a system whose current
// culture is en-US:
// First Name = | Fred|
// Last Name = | Opals|
// Price = | $100.00|
//
// First Name = |Fred |
// Last Name = |Opals |
// Price = |$100.00 |