문제

내 문제는 다음과 같습니다 (EN-US의 경우) :

Decimal.Parse("1,2,3,4") InvalidFormateXception을 던지는 대신 1234를 반환합니다.

대부분의 Windows 응용 프로그램 (Excel en 다른 언어에 대해서도 동일한 문제가 발생합니다 (다른 문자는 있지만).

이 문제를 해결하는 다른 소수점 구문 분석 라이브러리가 있습니까?

감사!

도움이 되었습니까?

해결책 2

통화를 수동으로 확인하기 위해 코드를 작성해야했습니다. 개인적으로, 모든 세계화 물건을 내장 한 것에 자부심을 느끼는 프레임 워크의 경우, .NET은 이것을 처리 할 것이 없습니다.

내 솔루션은 아래에 있습니다. 그것은 프레임 워크의 모든 로케일에서 작동합니다. 그러나 오리온이 아래에서 지적한 것처럼 마이너스 숫자를 지원하지 않습니다. 너희들은 어떻게 생각하세요?

    public static bool TryParseCurrency(string value, out decimal result)
    {
        result = 0;
        const int maxCount = 100;
        if (String.IsNullOrEmpty(value))
            return false;

        const string decimalNumberPattern = @"^\-?[0-9]{{1,{4}}}(\{0}[0-9]{{{2}}})*(\{0}[0-9]{{{3}}})*(\{1}[0-9]+)*$";

        NumberFormatInfo format = CultureInfo.CurrentCulture.NumberFormat;

        int secondaryGroupSize = format.CurrencyGroupSizes.Length > 1
                ? format.CurrencyGroupSizes[1]
                : format.CurrencyGroupSizes[0];

        var r = new Regex(String.Format(decimalNumberPattern
                                       , format.CurrencyGroupSeparator==" " ? "s" : format.CurrencyGroupSeparator
                                       , format.CurrencyDecimalSeparator
                                       , secondaryGroupSize
                                       , format.CurrencyGroupSizes[0]
                                       , maxCount), RegexOptions.Compiled | RegexOptions.CultureInvariant);
        return !r.IsMatch(value.Trim()) ? false : Decimal.TryParse(value, NumberStyles.Any, CultureInfo.CurrentCulture, out result);
    }

그리고 여기에 작동하는 테스트 (NUNIT)가 있습니다.

    [Test]
    public void TestCurrencyStrictParsingInAllLocales()
    {
        var originalCulture = CultureInfo.CurrentCulture;
        var cultures = CultureInfo.GetCultures(CultureTypes.SpecificCultures);
        const decimal originalNumber = 12345678.98m;
        foreach(var culture in cultures)
        {
            var stringValue = originalNumber.ToCurrencyWithoutSymbolFormat();
            decimal resultNumber = 0;
            Assert.IsTrue(DecimalUtils.TryParseCurrency(stringValue, out resultNumber));
            Assert.AreEqual(originalNumber, resultNumber);
        }
        System.Threading.Thread.CurrentThread.CurrentCulture = originalCulture;

    }

다른 팁

기본값이기 때문에 수천을 허용합니다 NumberStyles 사용 된 가치 Decimal.Parse (NumberStyles.Number) 포함 NumberStyles.AllowThousands.

수천 개의 분리기를 허용하지 않으려면 다음과 같이 해당 깃발을 제거 할 수 있습니다.

Decimal.Parse("1,2,3,4", NumberStyles.Number ^ NumberStyles.AllowThousands)

(위의 코드는 던질 것입니다 InvalidFormatException, 당신이 원하는 것은 무엇입니까?)

2 상 과정 에서이 작업을 수행 할 수 있습니다. 먼저 정보를 사용하여 수천 개의 분리기를 확인할 수 있습니다. CultureInfo.CurrentCulture.NumberFormat.NumberGroupSeparator 그리고 CultureInfo.CurrentCulture.NumberFormat.NumberGroupSizes 전달되지 않으면 예외를 던지고 번호를 Decimal.Parse();

Microsoft는 결코 해결되지 않은 일반적인 문제입니다. 따라서 1,2,3.00 (예 : 영어 문화)이 유효한 이유를 이해하지 못합니다! 테스트가 통과되지 않은 경우 그룹 크기를 검사하고 False/Exception (실패한 Double.parse)을 반환하려면 알고리즘을 구축해야합니다. MVC 애플리케이션에서 비슷한 문제가 있었는데, 유효성 검사기에서 구축하면 수천 명을 받아들이지 않습니다. 따라서 Double/Decimal/Float.parse를 사용하여 사용자 정의로 덮어 쓰고 그룹 크기를 검증하기 위해 논리를 추가합니다.

내 솔루션을 읽으려면 (MVC Custom Validator에 사용되지만 더 나은 Double/Decimal/Float.parse Generic Validator를 사용하여 사용하여 여기로 이동하십시오.https://stackoverflow.com/a/41916721/3930528

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top