Интернет-журнал "Домашняя лаборатория", 2007 №9
Шрифт:
public void TestParsing
{
string str,strpat;
//разбор предложения — создание массива слов
str = "А это пшеница, которая в темном чулане
хранится," +" в доме, который построил Джек!";
strpat =" +|, ";
Regex pat = new Regex(strpat);
string[] words;
words = pat.Split (str);
int i=1;
foreach(string word in words)
Console.WriteLine("{0}: {1}",i++,word);
} //TestParsing
Регулярное выражение, заданное строкой strpat, определяет множество разделителей. Заметьте, в качестве разделителя задан пробел, повторенный сколь угодно много раз, либо пара символов — запятая и пробел. Разделители задаются регулярными выражениями. Метод Split применяется к
Рис. 15.6. Регулярные выражения. Пример "Дом Джека"
Пример "Атрибуты"
Как уже говорилось, регулярные выражения особенно хороши при разборе сложных текстов. Примерами таковых могут быть различные справочники, различные текстовые базы данных, весьма популярные теперь XML-документы, разбором которых приходится заниматься. В качестве заключительного примера рассмотрим структурированный документ, строки которого содержат некоторые атрибуты, например, телефон, адрес и e-mail. Структуру документа можно задавать по-разному; будем предполагать, что каждый атрибут задается парой "имя: Значение" Наша задача состоит в том, чтобы выделить из строки соответствующие атрибуты. В таких ситуациях регулярное выражение удобно задавать в виде групп, где каждая группа соответствует одному атрибуту. Приведу начальный фрагмент кода очередной тестирующей процедуры, в котором описываются строки текста и образцы поиска:
public void TestAttributes
{
string s1 = "tel: (831-2) 94-20-55 string
s2 = "Адрес: 117926, Москва, 5-й Донской проезд, стр. 10, кв. 7";
string s3 = "e-mail: Valentin.Berestov@tverorg.ru
string s4 = s1+ s2 + s3;
string s5 = s2 + s1 + s3;
string pat1 = @"tel: \s(?<tel>\((\d|-)*\)\s(\d|-)+)\s";
string pat2 = @"Адрес: \s(?<addr>[0-9А-Яа-я \-\,\.]+)\s";
string pat3 = @"e-mail: \s(?<em>[a-zA-Z.0]+)\s";
string compat=pat1+pat2+pat3;
string tel="", addr = ""; em = "";
Строки s4 и s5 представляют строку разбираемого документа. Их две, для того чтобы можно было проводить эксперименты, когда атрибуты в документе представлены в произвольном порядке. Каждая из строк pat1, pat2, pat3 задает одну именованную группу в регулярном выражении, имена групп — tel, Адрес, e-mail — даются в соответствии со смыслом атрибутов. Сами шаблоны подробно описывать не буду — сделаю лишь одно замечание. Например, шаблон телефона исходит из того, что номеру предшествует код, заключенный в круглые скобки. Поскольку сами скобки играют особую роль, то для задания скобки как символа используется пара — "\ (". Это же касается и многих других символов, используемых в шаблонах, — точки, дефиса и т. п. Строка compat представляет составное регулярное выражение, содержащее все три группы. Строки tel, addr и em нам понадобятся для размещения в них результатов разбора. Применим вначале к строкам s4 и s5 каждый из шаблонов pat1, pat2, pat3 в отдельности и выделим соответствующий атрибут из строки. Вот код, выполняющий эти операции:
Regex reg1 = new Regex(pat1);
Match match1= reg1.Match(s4);
Console.WriteLine("Value =" + match1.Value);
tel= match1.Groups["tel"].Value;
Console.WriteLine(tel);
Regex reg2 = new Regex(pat2);
Match match2= reg2.Match(s5);
Console.WriteLine("Value =" + match2.Value);
addr= match2.Groups["addr"].Value;
Console.WriteLine(addr);
Regex reg3 = new Regex(pat3);
Match match3= reg3.Match(s5);
Console.WriteLine("Value =" + match3.Value);
em= match3.Groups["em"].Value;
Console.WriteLine(em);
Все
выполняется нужным образом — создаются именованные группы, к ним можно получить доступ и извлечь найденный значения атрибутов. А теперь попробуем решить ту же задачу одним махом, используя составной шаблон compat:Regex comreg = new Regex(compat);
Match commatch= comreg.Match(s4);
tel= commatch.Groups["tel"].Value;
Console.WriteLine(tel);
addr commatch.Groups["addr"].Value
Console.WriteLine(addr);
em= commatch.Groups["em"].Value;
Console.WriteLine(em);
}// TestAttributes
И эта задача успешно решается. Взгляните на результаты разбора текста.
Рис. 15.7. Регулярные выражения. Пример "Атрибуты"
На этом и завершим рассмотрение регулярных выражений а также лекции, посвященные работе с текстами в С#.
16. Классы
Две роли класса в ООП. Синтаксис описания класса. Поля и методы класса. Конструкторы и деструкторы. Статические поля и методы. Статические конструкторы. Поля только для чтения. Закрытые поля. Стратегии доступа к полям класса. Процедуры свойства. Индексаторы. Примеры.
Классы и ООП
Объектно-ориентированное программирование и проектирование построено на классах. Любую программную систему, выстроенную в объектном стиле, можно рассматривать как совокупность классов, возможно, объединенных в проекты, пространства имен, решения, как это делается при программировании в Visual Studio.Net.
Две роли классов
У класса две различные роли: модуля и типа данных. Класс — это модуль, архитектурная единица построения программной системы. Модульность построения — основное свойство программных систем. В ООП программная система, строящаяся по модульному принципу, состоит из классов, являющихся основным видом модуля. Модуль может не представлять собой содержательную единицу — его размер и содержание определяется архитектурными соображениями, а не семантическими. Ничто не мешает построить монолитную систему, состоящую из одного модуля — она может решать ту же задачу, что и система, состоящая из многих модулей.
Вторая роль класса не менее важна. Класс — это тип данных, задающий реализацию некоторой абстракции данных, характерной для задачи, в интересах которой создается программная система. С этих позиций классы — не просто кирпичики, из которых строится система. Каждый кирпичик теперь имеет важную содержательную начинку. Представьте себе современный дом, построенный из кирпичей, и дом будущего, где каждый кирпич выполняет определенную функцию: один следит за температурой, другой — за составом воздуха в доме. ОО-программная система напоминает дом будущего.
Состав класса, его размер определяется не архитектурными соображениями, а той абстракцией данных, которую должен реализовать класс. Если вы создаете класс Account, реализующий такую абстракцию как банковский счет, то в этот класс нельзя добавить поля из класса Саr, задающего автомобиль.
Объектно-ориентированная разработка программной системы основана на стиле, называемом проектированием от данных. Проектирование системы сводится к поиску абстракций данных, подходящих для конкретной задачи. Каждая из таких абстракций реализуется в виде класса, которые и становятся модулями — архитектурными единицами построения нашей системы. В основе класса лежит абстрактный тип данных.