Как преобразовать строку процента для удвоения?

Я имею строку как "1,5%" и хочу преобразовать ее для удвоения значения.

Это может быть сделано простое со следующим:

public static double FromPercentageString(this string value)
{
    return double.Parse(value.SubString(0, value.Length - 1)) / 100;
}

но я не хочу использовать этот подход парсинга.

Какой-либо другой подход с IFormatProvider или что-то вроде этого?

33
задан Nifle 31 January 2010 в 12:25
поделиться

5 ответов

Если вы заботитесь об обнаружении ошибок форматирования, я бы использовал TrimEnd, а не Replace. При замене ошибки форматирования не будут обнаружены.

var num = decimal.Parse( value.TrimEnd( new char[] { '%', ' ' } ) ) / 100M;

Это гарантирует, что значение должно быть некоторым десятичным числом, за которым следует любое количество пробелов и знаков процента, то есть оно должно, по крайней мере, начинаться со значения в правильном формате. Чтобы быть более точным, вы можете разделить на «%», не удаляя пустые записи, затем убедитесь, что есть только два результата, а второй пустой. Первым должно быть значение, которое нужно преобразовать.

var pieces = value.Split( '%' );
if (pieces.Length > 2  || !string.IsNullOrEmpty(pieces[1]))
{ 
    ... some error handling ... 
}
var num = decimal.Parse( pieces[0] ) / 100M;

Использование Replace позволит вам успешно и ошибочно анализировать IMO такие вещи, как:

  • % 1.5
  • 1% .5
  • 1.% 5

в дополнение к 1.5%

46
ответ дан 27 November 2019 в 17:23
поделиться

Это чувствительная к культуре, замените его так:

  value = value.Replace(System.Globalization.CultureInfo.CurrentCulture.NumberFormat.PercentSymbol, "");

затем разбирать его.

47
ответ дан 27 November 2019 в 17:23
поделиться

Только немного лучше, но меньше ошибок:

public static double FromPercentageString(this string value)
{
    return double.Parse(value.Replace("%","")) / 100;
}
9
ответ дан 27 November 2019 в 17:23
поделиться

TypeConverter предоставляет единый способ преобразования типов значений в другие типы, а также для доступа к стандартным значениям и подпространам. http://msdn.microsoft.com/en-us/library/system.componentmodel.typeconverter%28vs.80%29.aspx

Это, вероятно, излишки для одноразовых преобразований. Это гораздо полезнее при связывающих свойствах в ASP.NET или XAML или при разборке файлов конфигурации.

var result = new Percentage("1.5%");
double d = result.Value;

Процент и его типографвер определяются как:

[TypeConverter(typeof(PercentageConverter))]
public struct Percentage
{
    public double Value;

    public Percentage( double value )
    {
        Value = value;
    }

    public Percentage( string value )
    {
        var pct = (Percentage) TypeDescriptor.GetConverter(GetType()).ConvertFromString(value);
        Value = pct.Value;
    }

    public override string ToString()
    {
        return ToString(CultureInfo.InvariantCulture);
    }

    public string ToString(CultureInfo Culture)
    {
        return TypeDescriptor.GetConverter(GetType()).ConvertToString(null, Culture, this);
    }
}

public class PercentageConverter : TypeConverter
{
    static TypeConverter conv = TypeDescriptor.GetConverter(typeof(double));

    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
    {
        return conv.CanConvertFrom(context, sourceType);
    }

    public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
    {
        if (destinationType == typeof(Percentage)) {
            return true;
        }

        return conv.CanConvertTo(context, destinationType);
    }

    public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
    {
        if (value == null) {
            return new Percentage();
        }

        if (value is string) {
            string s = value as string;
            s = s.TrimEnd(' ', '\t', '\r', '\n');

            var percentage = s.EndsWith(culture.NumberFormat.PercentSymbol);
            if (percentage) {
                s = s.Substring(0, s.Length - culture.NumberFormat.PercentSymbol.Length);
            }

            double result = (double) conv.ConvertFromString(s);
            if (percentage) {
                result /= 100;
            }

            return new Percentage(result);
        }

        return new Percentage( (double) conv.ConvertFrom( context, culture, value ));
    }

    public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
    {
        if (!(value is Percentage)) {
            throw new ArgumentNullException("value");
        }

        var pct = (Percentage) value;

        if (destinationType == typeof(string)) {
            return conv.ConvertTo( context, culture, pct.Value * 100, destinationType ) + culture.NumberFormat.PercentSymbol;
        }

        return conv.ConvertTo( context, culture, pct.Value, destinationType );
    }
}
8
ответ дан 27 November 2019 в 17:23
поделиться

Это строка, независимо от того, что вы делаете с этим, чтобы удалить знак%, вы все еще должны разобрать его в двойной.

-1
ответ дан 27 November 2019 в 17:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: