数値文字列の解析

更新 : 2010 年 8 月

すべての数値型には、その数値の文字列形式を数値型に変換するための静的な解析メソッドとして、Parse および TryParse という 2 つのメソッドがあります。 これらのメソッドを使用すると、「標準の数値書式指定文字列」および「カスタム数値書式指定文字列」で説明する書式指定文字列を使用して作成した文字列を解析できます。 Parse メソッドと TryParse メソッドは、既定で、整数部のみを含む文字列を整数値に正しく変換できます。 また、整数部と小数部、桁区切り記号、および小数点記号を含む文字列を浮動小数点値に正しく変換できます。 操作が失敗すると、Parse メソッドからは例外がスローされ、TryParse メソッドからは false が返されます。

解析と書式プロバイダー

通常、数値の文字列形式はカルチャごとに異なります。 通貨記号、桁区切り記号、小数点記号など、数値文字列のすべての要素がカルチャごとに違います。 解析メソッドは、明示的または暗黙的に、それらのカルチャによる違いを認識する書式プロバイダーを使用します。 Parse メソッドまたは TryParse メソッドの呼び出しで書式プロバイダーが指定されていない場合は、現在のスレッドのカルチャ (NumberFormatInfo.CurrentInfo プロパティによって返される NumberFormatInfo オブジェクト) に関連付けられている書式プロバイダーが使用されます。

書式プロバイダーは IFormatProvider の実装で表されます。 このインターフェイスには、GetFormat メソッドという単一のメンバーがあります。このメソッドの単一のパラメーターは、書式を指定する型を表す Type オブジェクトです。 このメソッドが、書式情報を提供するオブジェクトを返します。 .NET Framework では、数値文字列を解析するために、次の 2 つの IFormatProvider の実装がサポートされています。

次の例では、配列の各文字列を Double 値に変換しようとしています。 まず、英語 (米国) カルチャの規則を反映する書式プロバイダーを使用して文字列の解析を試みます。 この操作で FormatException がスローされると、フランス語 (フランス) カルチャの規則を反映する書式プロバイダーを使用して文字列の解析を試みます。

Imports System.Globalization

Module Example
   Public Sub Main()
      Dim values() As String = { "1,304.16", "$1,456.78", "1,094", "152", 
                                 "123,45 €", "1 304,16", "Ae9f" }
      Dim number As Double
      Dim culture As CultureInfo = Nothing

      For Each value As String In values
         Try
            culture = CultureInfo.CreateSpecificCulture("en-US")
            number = Double.Parse(value, culture)
            Console.WriteLine("{0}: {1} --> {2}", culture.Name, value, number)
         Catch e As FormatException
            Console.WriteLine("{0}: Unable to parse '{1}'.", 
                              culture.Name, value)
            culture = CultureInfo.CreateSpecificCulture("fr-FR")
            Try
               number = Double.Parse(value, culture)
               Console.WriteLine("{0}: {1} --> {2}", culture.Name, value, number)
            Catch ex As FormatException
               Console.WriteLine("{0}: Unable to parse '{1}'.", 
                                 culture.Name, value)
            End Try
         End Try
         Console.WriteLine()
      Next
   End Sub
End Module
' The example displays the following output:
'    en-US: 1,304.16 --> 1304.16
'    
'    en-US: Unable to parse '$1,456.78'.
'    fr-FR: Unable to parse '$1,456.78'.
'    
'    en-US: 1,094 --> 1094
'    
'    en-US: 152 --> 152
'    
'    en-US: Unable to parse '123,45 €'.
'    fr-FR: Unable to parse '123,45 €'.
'    
'    en-US: Unable to parse '1 304,16'.
'    fr-FR: 1 304,16 --> 1304.16
'    
'    en-US: Unable to parse 'Ae9f'.
'    fr-FR: Unable to parse 'Ae9f'.
'    ' The example displays the following output:
'    en-US: 1,304.16 --> 1304.16
'    
'    en-US: Unable to parse '$1,456.78'.
'    fr-FR: Unable to parse '$1,456.78'.
'    
'    en-US: 1,094 --> 1094
'    
'    en-US: 152 --> 152
'    
'    en-US: Unable to parse '123,45 €'.
'    fr-FR: Unable to parse '123,45 €'.
'    
'    en-US: Unable to parse '1 304,16'.
'    fr-FR: 1 304,16 --> 1304.16
'    
'    en-US: Unable to parse 'Ae9f'.
'    fr-FR: Unable to parse 'Ae9f'.
using System;
using System.Globalization;

public class Example
{
   public static void Main()
   {
      string[] values = { "1,304.16", "$1,456.78", "1,094", "152", 
                          "123,45 €", "1 304,16", "Ae9f" };
      double number;
      CultureInfo culture = null;

      foreach (string value in values) {
         try {
            culture = CultureInfo.CreateSpecificCulture("en-US");
            number = Double.Parse(value, culture);
            Console.WriteLine("{0}: {1} --> {2}", culture.Name, value, number);
         }   
         catch (FormatException) {
            Console.WriteLine("{0}: Unable to parse '{1}'.", 
                              culture.Name, value);
            culture = CultureInfo.CreateSpecificCulture("fr-FR");
            try {
               number = Double.Parse(value, culture);
               Console.WriteLine("{0}: {1} --> {2}", culture.Name, value, number);
            }
            catch (FormatException) {
               Console.WriteLine("{0}: Unable to parse '{1}'.", 
                                 culture.Name, value);
            }
         }
         Console.WriteLine();
      }   
   }
}
// The example displays the following output:
//    en-US: 1,304.16 --> 1304.16
//    
//    en-US: Unable to parse '$1,456.78'.
//    fr-FR: Unable to parse '$1,456.78'.
//    
//    en-US: 1,094 --> 1094
//    
//    en-US: 152 --> 152
//    
//    en-US: Unable to parse '123,45 €'.
//    fr-FR: Unable to parse '123,45 €'.
//    
//    en-US: Unable to parse '1 304,16'.
//    fr-FR: 1 304,16 --> 1304.16
//    
//    en-US: Unable to parse 'Ae9f'.
//    fr-FR: Unable to parse 'Ae9f'.

解析と NumberStyles の値

解析操作で処理できるスタイル要素 (空白文字、桁区切り記号、小数点記号など) は、NumberStyles 列挙値で定義されます。 既定では、整数値を表す文字列は、NumberStyles.Integer 値を使用して解析されます。このスタイルでは、数字、先頭と末尾の空白文字、および先頭の符号だけを使用できます。 浮動小数点値を表す文字列は、NumberStyles.Float 値と NumberStyles.AllowThousands 値の組み合わせで解析されます。この複合スタイルでは、10 進数の数字に加え、先頭と末尾の空白文字、先頭の符号、小数点記号、桁区切り記号、および指数を使用できます。 NumberStyles 型のパラメーターを含む Parse メソッドまたは TryParse メソッドのオーバーロードを呼び出し、NumberStyles フラグを 1 つ以上設定することで、解析操作を成功させるために文字列で使用できるスタイル要素を制御することができます。

たとえば、桁区切り記号を含む文字列を Int32.Parse(String) メソッドを使用して Int32 値に変換することはできませんが、次の例のように、NumberStyles.AllowThousands フラグを使用すると変換が成功します。

Imports System.Globalization

Module Example
   Public Sub Main()
      Dim value As String = "1,304"
      Dim number As Integer
      Dim provider As IFormatProvider = CultureInfo.CreateSpecificCulture("en-US")
      If Int32.TryParse(value, number) Then
         Console.WriteLine("{0} --> {1}", value, number)
      Else
         Console.WriteLine("Unable to convert '{0}'", value)
      End If

      If Int32.TryParse(value, NumberStyles.Integer Or NumberStyles.AllowThousands, 
                        provider, number) Then
         Console.WriteLine("{0} --> {1}", value, number)
      Else
         Console.WriteLine("Unable to convert '{0}'", value)
      End If
   End Sub
End Module
' The example displays the following output:
'       Unable to convert '1,304'
'       1,304 --> 1304
using System;
using System.Globalization;

public class Example
{
   public static void Main()
   {
      string value = "1,304";
      int number;
      IFormatProvider provider = CultureInfo.CreateSpecificCulture("en-US");
      if (Int32.TryParse(value, out number))
         Console.WriteLine("{0} --> {1}", value, number);
      else
         Console.WriteLine("Unable to convert '{0}'", value);

      if (Int32.TryParse(value, NumberStyles.Integer | NumberStyles.AllowThousands, 
                        provider, out number))
         Console.WriteLine("{0} --> {1}", value, number);
      else
         Console.WriteLine("Unable to convert '{0}'", value);
   }
}
// The example displays the following output:
//       Unable to convert '1,304'
//       1,304 --> 1304
Caution メモ注意

解析操作では、常に特定のカルチャの書式指定規則が使用されます。CultureInfo オブジェクトまたは NumberFormatInfo オブジェクトを渡すことによってカルチャを指定していない場合は、現在のスレッドに関連付けられているカルチャが使用されます。

次の表に、NumberStyles 列挙体のメンバーと、それらによる解析操作への影響を示します。

NumberStyles の値

解析対象の文字列に対する影響

NumberStyles.None

数字だけを使用できます。

NumberStyles.AllowDecimalPoint

小数点記号と小数を使用できます。 整数値については、小数部の数値として 0 だけを使用できます。 有効な小数点記号は、NumberFormatInfo.NumberDecimalSeparator プロパティまたは NumberFormatInfo.CurrencyDecimalSeparator プロパティによって決まります。

NumberStyles.AllowExponent

"e" または "E" という文字を使用して指数表記を示すことができます。 詳細については、「NumberStyles」を参照してください。

NumberStyles.AllowLeadingWhite

先頭の空白文字を使用できます。

NumberStyles.AllowTrailingWhite

末尾の空白文字を使用できます。

NumberStyles.AllowLeadingSign

数字の前に正または負の符号を使用できます。

NumberStyles.AllowTrailingSign

数字の後に正または負の符号を使用できます。

NumberStyles.AllowParentheses

かっこを使用して負の値を示すことができます。

NumberStyles.AllowThousands

桁区切り記号を使用できます。 桁区切り記号文字は、NumberFormatInfo.NumberGroupSeparator プロパティまたは NumberFormatInfo.CurrencyGroupSeparator プロパティによって決まります。

NumberStyles.AllowCurrencySymbol

通貨記号を使用できます。 通貨記号は NumberFormatInfo.CurrencySymbol プロパティで定義されます。

NumberStyles.AllowHexSpecifier

解析対象の文字列が 16 進数と解釈されます。 16 進数の数字を表す 0 ~ 9、A ~ F、および a ~ f を使用できます。 このフラグは、整数値の解析でのみ使用できます。

さらに、NumberStyles 列挙体には、複数の NumberStyles フラグで構成される次の複合スタイルも用意されています。

NumberStyles の複合値

含まれるメンバー

NumberStyles.Integer

NumberStyles.AllowLeadingWhiteNumberStyles.AllowTrailingWhite、および NumberStyles.AllowLeadingSign の各スタイルが含まれます。 整数値の解析には、既定ではこのスタイルが使用されます。

NumberStyles.Number

NumberStyles.AllowLeadingWhiteNumberStyles.AllowTrailingWhiteNumberStyles.AllowLeadingSignNumberStyles.AllowTrailingSignNumberStyles.AllowDecimalPoint、および NumberStyles.AllowThousands の各スタイルが含まれます。

NumberStyles.Float

NumberStyles.AllowLeadingWhiteNumberStyles.AllowTrailingWhiteNumberStyles.AllowLeadingSignNumberStyles.AllowDecimalPoint、および NumberStyles.AllowExponent の各スタイルが含まれます。

NumberStyles.Currency

NumberStyles.AllowExponentNumberStyles.AllowHexSpecifier を除くすべてのスタイルが含まれます。

NumberStyles.Any

NumberStyles.AllowHexSpecifier を除くすべてのスタイルが含まれます。

NumberStyles.HexNumber

NumberStyles.AllowLeadingWhiteNumberStyles.AllowTrailingWhite、および NumberStyles.AllowHexSpecifier の各スタイルが含まれます。

解析と Unicode の数字

Unicode 規格では、さまざまな書記体系での数字に対応するコード ポイントが定義されています。 たとえば、U+0030 ~ U+0039 のコード ポイントは基本ラテン数字の 0 ~ 9、U+09E6 ~ U+09EF のコード ポイントはベンガル語の数字の 0 ~ 9、U+FF10 ~ U+FF19 のコード ポイントはフル幅の数字の 0 ~ 9 を表します。 ただし、解析メソッドで認識される数字は、コード ポイントが U+0030 ~ U+0039 の基本ラテン数字の 0 ~ 9 だけです。 それ以外の数字を含む文字列を数値解析メソッドに渡した場合、メソッドから FormatException がスローされます。

Int32.Parse メソッドを使用して、複数の書記体系の数字で構成された文字列を解析する例を次に示します。 出力を見るとわかるように、基本ラテン数字の解析は成功しますが、フル幅、アラブインド言語、およびベンガル語の数字の解析は失敗します。

Module Example
   Public Sub Main()
      Dim value As String
      ' Define a string of basic Latin digits 1-5.
      value = ChrW(&h31) + ChrW(&h32) + ChrW(&h33) + ChrW(&h34) + ChrW(&h35)
      ParseDigits(value)

      ' Define a string of Fullwidth digits 1-5.
      value = ChrW(&hff11) + ChrW(&hff12) + ChrW(&hff13) + ChrW(&hff14) + ChrW(&hff15)
      ParseDigits(value)

      ' Define a string of Arabic-Indic digits 1-5.
      value = ChrW(&h661) + ChrW(&h662) + ChrW(&h663) + ChrW(&h664) + ChrW(&h665)
      ParseDigits(value)

      ' Define a string of Bengali digits 1-5.
      value = ChrW(&h09e7) + ChrW(&h09e8) + ChrW(&h09e9) + ChrW(&h09ea) + ChrW(&h09eb)
      ParseDigits(value)
   End Sub

   Sub ParseDigits(value As String)
      Try
         Dim number As Integer = Int32.Parse(value)
         Console.WriteLine("'{0}' --> {1}", value, number)
      Catch e As FormatException
         Console.WriteLine("Unable to parse '{0}'.", value)      
      End Try     
   End Sub
End Module
' The example displays the following output:
'       '12345' --> 12345
'       Unable to parse '12345'.
'       Unable to parse '١٢٣٤٥'.
'       Unable to parse '১২৩৪৫'.
using System;

public class Example
{
   public static void Main()
   {
      string value;
      // Define a string of basic Latin digits 1-5.
      value = "\u0031\u0032\u0033\u0034\u0035";
      ParseDigits(value);

      // Define a string of Fullwidth digits 1-5.
      value = "\uFF11\uFF12\uFF13\uFF14\uFF15";
      ParseDigits(value);

      // Define a string of Arabic-Indic digits 1-5.
      value = "\u0661\u0662\u0663\u0664\u0665";
      ParseDigits(value);

      // Define a string of Bengali digits 1-5.
      value = "\u09e7\u09e8\u09e9\u09ea\u09eb";
      ParseDigits(value);
   }

   static void ParseDigits(string value)
   {
      try {
         int number = Int32.Parse(value);
         Console.WriteLine("'{0}' --> {1}", value, number);
      }   
      catch (FormatException) {
         Console.WriteLine("Unable to parse '{0}'.", value);      
      }     
   }
}
// The example displays the following output:
//       '12345' --> 12345
//       Unable to parse '12345'.
//       Unable to parse '١٢٣٤٥'.
//       Unable to parse '১২৩৪৫'.

参照

参照

NumberStyles

概念

型の書式設定

その他の技術情報

文字列の解析

履歴の変更

日付

履歴

理由

2010 年 8 月

全面的に改訂。

情報の拡充