Кратко съдържание



страница66/73
Дата21.07.2018
Размер9.03 Mb.
#76887
1   ...   62   63   64   65   66   67   68   69   ...   73

Парсване на типове


Задачата за получаване на обект въз основа на низ е често срещана в практиката. Низът може да е получен като вход от потребителя или взет от база данни. Целта ни е да конструираме обект от стойността му, за да бъде тя по-лесно използваема в нашето приложение.

В .NET Framework за решението на тази задача е предоставено специално средство – методът Parse(string), който прави синтактичен анализ (пар­сване). Механизмът на неговото действие е следният: на метода Parse(string) на обект, поддържащ парсване, се подава низ, който зада­ва валидна стойност за инстанция на такъв обект. Методът Parse(string) обработва подадения низ и връща инстанция на обекта със зададената стойност. Така методът изпълнява ролята на конструктор при създаването на обекта.

Методът Parse(string) реализира противоположната функция на метода ToString(). Подобно на него, той използва обект, доставчик на формат (FormatProvider), за да определи какво тълкуване да направи на пода­дения му символен низ.

Методът Parse(string) се поддържа стандартно от всички числени типо­ве, от типа DateTime, от изброените типове (enums), както и от типовете Char и Boolean.


Парсване на числови типове


Методът Parse(string) може да парсва числа, записани в различни фор­мати. Вариантът Parse(string, NumberStyles) позволява да се зада­ват раз­лични опции при парсването. NumberStyles дефинира битово поле, в което всеки бит обозначава дали е позволено или не определено пове­дение на входящия низ. В таблицата са дадени по-важните флагове и значението, което NumberStyles им придава:

Име на флага

Описание

None

Специални знаци не са позволени.

AllowLeadingWhite, AllowTrailingWhite

Указва, че при парсването трябва да се прене­брегнат празни места в началото / в края.

AllowLeadingSign

Указва, че числовият низ може да има знак в началото. Валидните символи за знак се опре­делят културата, от свойствата PositiveSign и NegativeSign на NumberFormatInfo.

AllowParentheses

Указва, че числовият низ може да бъде заграден в двойка скоби.

AllowDecimalPoint

Указва, че числовият низ може да съдържа десетична запетая. Валидните знаци за десе­тична запетая се определят от свойството NumberFormatInfo на използваната култура.

AllowThousands

Указва, че числовият низ може да съдържа групиращи разделители - разделящи например стотиците от хилядите. Валидните разделители се определят от NumberFormatInfo свойството на използваната култура.

AllowExponent

Указва дали числовият низ може да е в експо­ненциален запис.

AllowCurrencySymbol

Указва, че числовият низ се приема като валутна информация, ако има наличен символ за валута; в противен случай се приема като число. Валидните символи за валута се определят от свойството CurrencySymbol на NumberFormatInfo.

AllowHexSpecifier

Указва, че числовият низ представлява шест­найсетична стойност. Валидните шестнайсетич­ни стойности съдържат цифрите 0-9 и шестнай­сетичните цифри A-F и a-f. Низовете не трябва да имат "0x" в началото.

Тъй като за всяка настройка се използва един бит от битовото поле, е лесно да се зададе комбинация от настройки. Това можем да направим с побитовия оператор | по следния начин:

string price = "3,14159";

double unitPrice = Double.Parse(price,

NumberStyles.AllowCurrencySymbol |

NumberStyles.AllowDecimalPoint |

NumberStyles.AllowExponent |

NumberStyles.AllowLeadingWhite |

NumberStyles.AllowParentheses |

NumberStyles.AllowThousands |

NumberStyles.AllowTrailingWhite);


С този код указваме, че желаем да получим число от потребителски низ, като позволяваме символ за валута, десетична запетая, експонента, праз­ни символи в началото, двойка скоби, разделители на хилядите и празни символи в края. Някои от тези параметри зависят от зададените настройки за култура. По-нататък ще разгледаме влиянието на зададената култура върху метода Parse(…).

За да не се налага всеки път да изброяваме толкова много флагове, можем да използваме предефинираните комбинации от флагове в изброе­ния тип NumberStyles – стойностите Integer, Number, Float, Currency, HexNumber и т. н., имената на които подсказват за какво служат. Ето при­мер за използването на предефинирана комбинация от флагове при парс­ването на число:



string price = "17,34 лв";

double unitPrice = Double.Parse(price, NumberStyles.Currency);


Влияние на културата върху парсването


За да зададем изрично желаните настройки на културата, трябва да използваме варианта Parse(string, IFormatProvider). Той приема като параметър обект, имплементиращ IFormatProvider, който указва форма­тиращите настройки за използваната култура. IFormatProvider обектът включва информация за форматирането на числата (разделител за хиля­дите, знак за дробната част и др.) и за форматирането на валутата (сим­вол за валута и местоположение).

Методът Parse(string, NumberStyles, IFormatProvider) комбинира предходните два варианта на метода. С този метод може да се зададат едновременно специфичен формат за парсваното число и специфична култура.


Парсване на числови типове – пример


Нека разгледаме няколко примера как можем да парсваме числа като задаваме комбинация от флагове за техния формат и култура:

static void Main()

{

// Set the default formatting for current thread.



// Invariant culture will be used for Console.WriteLine()

System.Threading.Thread.CurrentThread.CurrentCulture =

CultureInfo.InvariantCulture;
string s = " 000012,54 лв ";

double value = Double.Parse(s, NumberStyles.Currency,

new CultureInfo("bg-BG"));

Console.WriteLine(value); // 12.54


s = "17,345,342.38";

value = Double.Parse(s, NumberStyles.Number,

new CultureInfo("en-US"));

Console.WriteLine(value); // 17345342.38


value = Double.Parse(s, NumberStyles.Number,

new CultureInfo("bg-BG"));

// System.FormatException: Input string was not in a

// correct format.

}


При първото обръщение към Parse() подаваме низ, съдържащ инфор­мация за цена в български формат. Задаваме параметър NumberStyles. Currency, за да укажем, че това е валута и указваме, че използваме кул­турата за България ("bg-BG"), за да може правилно да бъдат разпознати символът за валута ("лв") и знакът за дробната част (",").

При второто обръщение задаваме, че очакваме да прочетем число. Тъй като указваме американска култура ("en-US"), коректно се разпознават знакът "," като разделител на хилядите и знакът "." като обозначение за начало на дробната част. За сравнение сме показали, че ако опитаме да прочетем това число с българска култура, ще се получи изключение от тип FormatException защото в България символът "," се използва за отде­ляне на дробната част при реалните числа.


Парсване на дати


Класът DateTime имплементира метод Parse(…), който ни позволява да полу­чим нов DateTime обект от низове, съдържащи дати в текстов вид.

Нека разгледаме метода DateTime.Parse(…) със сигнатура Parse(string, IFormatProvider, DateTimeStyles). Начинът на записване на датата и часа се взимат от IFormatProvider. Изброеният тип DateTimeStyles зада­ва допълнителни настройки (дали низът може да съдържа празно място, дали да се приема текущата дата, когато е зададен само час и др.).

Освен метода Parse(…) класът DateTime имплементира и друг метод за парсване на дати и часове – ParseExact(string date, string format, IFormatProvider). Този метод позволява задаване на точния формат на датата и часа, които трябва да се парснат. За разлика от Parse(…), ParseExact(…) няма да обработи правилно датата, ако тя не отговаря абсолютно точно на зададения формат.

Форматът на датите и часовете се задава чрез шаблони за форматиране, които са същите, които разгледахме в секцията за форматиране на дати.


Парсване на дати – пример


За да илюстрираме работата с Parse(…) и ParseExact(…) ще използваме следните примери:

DateTime dt = DateTime.Parse(" Thursday,August 05, 2004 ",

new CultureInfo("en-US"), DateTimeStyles.AllowWhiteSpaces);

Thread.CurrentThread.CurrentCulture =

CultureInfo.InvariantCulture;

Console.WriteLine("{0:d}", dt);

// Result: 08/05/2004


dt = DateTime.ParseExact("5.08.2004 г. 15:47:00 ч.",

"d.MM.yyyy г. HH:mm:ss ч.", new CultureInfo("bg-BG"));

Console.WriteLine("{0:d.MM.yyyy HH:mm:ss}", dt);

// Result: 5.08.2004 15:47:00


dt = DateTime.ParseExact("15:53:21", "HH:mm:ss",

CultureInfo.InvariantCulture);

Console.WriteLine("{0:HH:mm:ss}", dt);

// Result: 15:53:21



При първото обръщение към метода Parse(…) указваме, че желаем да конструираме нов обект от тип DateTime, като стойността се взима от низа " Thursday,August 05, 2004 ". Вторият параметър създава нов обект CultureInfo, който указва използването на настройките за култура на САЩ (US). От изброения тип DateTimeStyles се указва стойността DateTimeStyles.AllowWhiteSpaces, която разрешава низът, който се пар­сва, да съдържа интервали, табулации и други символи за празно прост­ранство.

Следващата стъпка е да зададем инвариантна култура за текущата нишка. Както видяхме в секцията за култури, инвариантната култура, не е свър­за­на с конкретно местонахождение. В резултат на тази операция следва­щите извиквания на WriteLine(…) няма да отпечатват датата с настрой­ките на операционната система, а по неутрален относно държавата начин.

За да бъде извършено правилно следващото разпознаване, подаваме на метода ParseExact(…) низ с дата, която отговаря символ по символ на шаблона на зададения от нас формат. Задаваме българска култура, за да бъдат разпознати правилно символите за час и година.

При второто обръщение към ParseExact(…) подаваме като култура CultureInfo.InvariantCulture за да укажем, че низът, който парсваме, не съдържа символи за час, година и т. н.





Сподели с приятели:
1   ...   62   63   64   65   66   67   68   69   ...   73




©obuch.info 2024
отнасят до администрацията

    Начална страница