다음을 통해 공유


.NET에서 숫자 문자열 구문 분석

모든 숫자 형식에는 ParseTryParse 두 개의 정적 구문 분석 메서드가 있으며, 이를 통해 숫자의 문자열 표현을 숫자 형식으로 변환할 수 있습니다. 이러한 메서드를 사용하면 표준 숫자 형식 문자열 및 사용자 지정 숫자 형식 문자열에 설명된 형식 문자열을 사용하여 생성된 문자열을 구문 분석할 수 있습니다. 기본적으로 ParseTryParse 메서드는 정수로만 구성된 문자열을 정수 값으로 변환할 수 있습니다. 정수 및 소수 자릿수, 그룹 구분 기호 및 소수 구분 기호를 포함하는 문자열을 부동 소수점 값으로 성공적으로 변환할 수 있습니다. Parse 메서드는 작업이 실패하면 예외를 throw하며, TryParse 메서드는 false를 반환합니다.

비고

.NET 7부터, .NET의 숫자 형식도 System.IParsable<TSelf> 인터페이스를 구현하여 IParsable<TSelf>.ParseIParsable<TSelf>.TryParse 메서드를 정의합니다.

파싱 및 형식 제공자

일반적으로 숫자 값의 문자열 표현은 문화권에 따라 다릅니다. 통화 기호, 그룹(또는 수천) 구분 기호 및 소수 구분 기호와 같은 숫자 문자열의 요소는 모두 문화권에 따라 다릅니다. 구문 분석 방법은 암시적으로 또는 명시적으로 이러한 문화권별 변형을 인식하는 형식 공급자를 사용합니다. Parse 또는 TryParse 메서드를 호출할 때 형식 공급자를 지정하지 않으면 현재 문화권과 연결된 형식 공급자(NumberFormatInfo 속성에서 반환된 NumberFormatInfo.CurrentInfo 오브젝트)가 사용됩니다.

형식 공급자는 IFormatProvider 구현으로 나타납니다. 이 인터페이스에는 서식을 지정할 형식을 나타내는 Type 개체를 단일 매개 변수로 갖는 단일 멤버 메서드 GetFormat가 있습니다. 이 메서드는 서식 정보를 제공하는 개체를 반환합니다. .NET은 숫자 문자열을 구문 분석하기 위해 다음 두 IFormatProvider 가지 구현을 지원합니다.

다음 예제에서는 배열의 각 문자열을 값으로 Double 변환하려고 시도합니다. 먼저 영어(미국) 문화권의 규칙을 반영하는 형식 공급자를 사용하여 문자열을 구문 분석하려고 합니다. 이 연산이 FormatException를 발생하면, 프랑스어(프랑스) 문화권의 규칙을 반영하는 형식 제공자를 사용하여 문자열을 구문 분석하려고 합니다.

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($"{culture.Name}: {value} --> {number}");
         }
         catch (FormatException) {
            Console.WriteLine($"{culture.Name}: Unable to parse '{value}'.");
            culture = CultureInfo.CreateSpecificCulture("fr-FR");
            try {
               number = Double.Parse(value, culture);
               Console.WriteLine($"{culture.Name}: {value} --> {number}");
            }
            catch (FormatException) {
               Console.WriteLine($"{culture.Name}: Unable to parse '{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'.
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'.

구문 분석과 NumberStyles 값 설명

구문 분석 작업에서 처리할 수 있는 스타일 요소(예: 공백, 그룹 구분 기호 및 소수 구분 기호)는 열거형 값으로 NumberStyles 정의됩니다. 기본적으로 정수 값을 나타내는 문자열은 숫자, 앞뒤 공백 및 앞에 오는 기호만 허용하는 NumberStyles.Integer 값을 사용하여 분석됩니다. 부동 소수점 값을 나타내는 문자열은 NumberStyles.FloatNumberStyles.AllowThousands 값을 결합하여 구문 분석됩니다. 이 결합 스타일은 소수 자릿수뿐만 아니라, 선행 및 후행 공백, 선행 기호, 소수 구분 기호, 그룹 구분 기호 및 지수를 허용합니다. 형식 NumberStyles 의 매개 변수를 포함하는 또는 TryParse 메서드의 Parse 오버로드를 호출하고 하나 이상의 NumberStyles 플래그를 설정하면 구문 분석 작업이 성공하기 위해 문자열에 있을 수 있는 스타일 요소를 제어할 수 있습니다.

예를 들어 그룹 구분 기호가 포함된 문자열은 메서드를 사용하여 Int32.Parse(String) 값으로 변환 Int32 할 수 없습니다. 그러나 다음 예제와 같이 플래그를 NumberStyles.AllowThousands 사용하면 변환에 성공합니다.

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($"{value} --> {number}");
      else
         Console.WriteLine($"Unable to convert '{value}'");

      if (Int32.TryParse(value, NumberStyles.Integer | NumberStyles.AllowThousands,
                        provider, out number))
         Console.WriteLine($"{value} --> {number}");
      else
         Console.WriteLine($"Unable to convert '{value}'");
   }
}
// The example displays the following output:
//       Unable to convert '1,304'
//       1,304 --> 1304
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

경고

구문 분석 작업은 항상 특정 문화권의 서식 규칙을 사용합니다. CultureInfo 또는 NumberFormatInfo 개체를 전달하여 문화권을 지정하지 않으면, 현재 스레드와 연결된 문화권이 사용됩니다.

다음 표에서는 열거형의 멤버를 NumberStyles 나열하고 구문 분석 작업에 미치는 영향을 설명합니다.

NumberStyles 값 구문 분석할 문자열에 미치는 영향
NumberStyles.None 숫자 숫자만 허용됩니다.
NumberStyles.AllowDecimalPoint 소수 구분 기호와 소수 자릿수가 허용됩니다. 정수 값의 경우 소수 자릿수로 0만 허용됩니다. 유효한 10진수 구분 기호는 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.AllowBinarySpecifier 구문 분석할 문자열은 이진 숫자로 해석됩니다. 이진 숫자 0과 1을 포함할 수 있습니다. 이 플래그는 정수 값을 구문 분석하는 데만 사용할 수 있습니다.

또한 NumberStyles 열거형은 여러 NumberStyles 플래그를 포함하는 복합 스타일을 다음과 같이 제공합니다.

복합 NumberStyles 값 회원 포함
NumberStyles.Integer NumberStyles.AllowLeadingWhite, NumberStyles.AllowTrailingWhiteNumberStyles.AllowLeadingSign 스타일을 포함합니다. 정수 값을 구문 분석하는 데 사용되는 기본 스타일입니다.
NumberStyles.Number NumberStyles.AllowLeadingWhite, NumberStyles.AllowTrailingWhite, NumberStyles.AllowLeadingSign, NumberStyles.AllowTrailingSignNumberStyles.AllowDecimalPointNumberStyles.AllowThousands 스타일을 포함합니다.
NumberStyles.Float NumberStyles.AllowLeadingWhite, NumberStyles.AllowTrailingWhite, NumberStyles.AllowLeadingSignNumberStyles.AllowDecimalPointNumberStyles.AllowExponent 스타일을 포함합니다.
NumberStyles.Currency 를 제외한 NumberStyles.AllowExponentNumberStyles.AllowHexSpecifier모든 스타일을 포함합니다.
NumberStyles.Any 를 제외한 NumberStyles.AllowHexSpecifier모든 스타일을 포함합니다.
NumberStyles.HexNumber NumberStyles.AllowLeadingWhite, NumberStyles.AllowTrailingWhiteNumberStyles.AllowHexSpecifier 스타일을 포함합니다.
NumberStyles.BinaryNumber NumberStyles.AllowLeadingWhite, NumberStyles.AllowTrailingWhiteNumberStyles.AllowBinarySpecifier 스타일을 포함합니다.

바이너리 및 16진수 빅인티저 구문 분석

또는AllowHexSpecifier 또는 AllowBinarySpecifier 플래그로 BigInteger를 구문 분석할 때 입력 문자열은 문자열의 길이대로 정확히 16진수/이진수로 해석됩니다. 예를 들어, "11"를 이진 BigInteger로 구문 분석하면, 이는 정확히 2자리의 부호 있는 2의 보수 값으로 해석되는 11가 됩니다. 양수 결과를 원하는 경우 다음과 같이 "011" 구문 분석되는 선행0을 추가합니다3.

구문 분석 및 유니코드 숫자

유니코드 표준은 다양한 쓰기 시스템의 숫자 코드 포인트를 정의합니다. 예를 들어 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 사용하여 여러 쓰기 시스템의 숫자로 구성된 문자열을 구문 분석합니다. 예제의 출력에서 알 수 있듯이 기본 라틴어 숫자를 구문 분석하는 시도는 성공하지만 전체 위도, 아랍어-인딕 및 벵골어 숫자를 구문 분석하려는 시도는 실패합니다.

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 Bangla digits 1-5.
      value = "\u09e7\u09e8\u09e9\u09ea\u09eb";
      ParseDigits(value);
   }

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

참고하십시오