Файл: сновы программирования на языке Pascal.pdf

ВУЗ: Не указан

Категория: Курсовая работа

Дисциплина: Не указана

Добавлен: 23.04.2023

Просмотров: 326

Скачиваний: 1

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

Действительно, теперь «жадность» квантификатора ограничена пятью символами, поэтому вместо полных слов мы будем находить фрагменты слов, состоящие из не более пяти подряд идущих словообразующих символов, и, в полном соответствии с указанным выражением замены, любой найденный фрагмент будет заменяться на такой же фрагмент, обрамленный угловыми скобками.

Для правильного решения задачи нам необходимо дополнительно потребовать, чтобы найденный фрагмент был ограничен пробелами или началом/концом строки. При этом пробелы не должны входить в найденные фрагменты, так как в противном случае они попадут «внутрь» добавленных угловых скобок. Таким образом, в регулярное выражение надо добавить элементы, которые определенным образом повлияют на поиск требуемых подстрок, но не появятся в самих найденных подстроках. Подобные элементы языка регулярных выражений называются директивами нулевой длины.

В нашем случае проще всего воспользоваться директивой \b, обозначающей границу слова, т. е. позицию в строке, разделяющую начало/конец слова и предшествующий/следующий пробел (или другой символ-разделитель) или начало/конец строки. Для того чтобы регулярное выражение выделяло из строки полные слова, достаточно добавить директиву \b в его начало и конец:

Writeln(Regex.Replace(s, '\b\w{1,5}\b', '<$0>'));

С использованием данного варианта регулярного выражения задача будет решена правильно.
Иногда требуется выполнить замену только для некоторого количества начальных вхождений нужных подстрок. Например, в нашей задаче можно дополнительно потребовать, чтобы в угловые скобки было заключено только первое из слов, имеющих длину не более 5 символов. Такая возможность отсутствует в классовом методе Replace, однако имеется в одноименном экземплярном методе. Таким образом, для решения задачи надо создать экземпляр класса Regex и вызвать для него метод Replace:

var r := new Regex('\b\w{1,5}\b');

Writeln(r.Replace(s, '<$0>', 1));

В результате будет выведена строка

<Текст>   Клавиатура  Поле    Монитор.

Для объекта r типа Regex можно вызывать все ранее рассмотренные методы класса Regex: Split, IsMatch, Match, Matches и Replace. При этом само регулярное выражение не указывается, так как оно определяется в конструкторе объекта, однако можно указать дополнительные параметры, отсутствующие в одноименных классовых методах (например, можно дополнительно указать индекс символа исходной строки, начиная с которого нужно выполнять требуемое действие).

Довольно часто при замене приходится выполнять преобразования, которые нельзя описать в виде выражения замены, даже если использовать в нем специальные подстановки. Предположим, что нам требуется добавить к каждому слову исходной строки информацию о его длине, заключив ее в круглые скобки (например, строку Текст надо заменить на Текст(5). Для выполнения подобных «сложных» замен предусмотрен вариант метода Replace, в котором в качестве параметра, определяющего способ замены, указывается не строка, а делегат (процедурная переменная). Этот делегат должен указывать на функцию, которая определяет, каким образом надо преобразовывать каждое найденное вхождение в исходной строке. Единственным параметром данной функции должно быть текущее найденное вхождение (типа Match), а возвращаемым значением является строка, на которую надо заменить найденное вхождение.


Воспользуемся данным вариантом метода Replace, предварительно описав требуемую функцию:

function AddLength(m: Match): string;

begin

result := m.Value + '(' + IntToStr(m.Length) + ')';

end;

...

Writeln(Regex.Replace(s, '\w+', AddLength));

При обработке приведенной ранее тестовой строки будет выведена строка

Текст(5)   Клавиатура(10)  Поле(4)    Монитор(7)

Заметим, что без предварительного описания функции AddLength можно обойтись, если воспользоваться соответствующим лямбда-выражением, указав его в качестве третьего параметра метода Replace:

Writeln(Regex.Replace(s, '\w+',(m: Match) -> m.Value + '(' + IntToStr(m.Length) + ')'));

Еще одним важным элементом языка регулярных выражений являются группы. Группу образует часть регулярного выражения, заключенная в круглые скобки. Приведем простейший пример использования группы: (ab)+. Данное выражение означает строку, в которой текст ab повторяется один или более раз (например, ababab). Понятно, что без группирования символов смысл выражения будет другим: ab+ означает строку, начинающуюся с символа a, за которым следует один или более символов b (например, abbb).

Однако простой группировкой роль групп в языке регулярных выражений не ограничивается. Каждая группа в регулярном выражении получает свой порядковый номер и может быть использована в последующих фрагментах регулярного выражения с помощью специальной директивы \N, где N - порядковый номер группы (можно также присваивать некоторым группам имена-идентификаторы - см. третью часть статьи). Порядок нумерации групп определяется по расположению их открывающих скобок. Нумерация групп начинается от 1 (все найденное вхождение также считается группой; этой особой группе присваивается номер 0).

Чтобы познакомиться с применением групп в регулярных выражениях, рассмотрим два примера. В первом примере мы найдем все слова исходной строки, начинающиеся и оканчивающиеся на одну и ту же букву:

foreach a: match in Regex.Matches(s, '\b(\w)\w*\1\b') do

write(a.Value, ' ');

Если строка s содержит текст Каучук   барабан  алгебра  диафрагма, то на экран будет выведено слово алгебра.
Обсудим смысл элементов регулярного выражения. В начале и конце выражения указываются директивы нулевой длины \b, обеспечивающие поиск полных слов (если не указывать эти директивы, то при обработке этой же строки мы получим следующий результат: учу бараб алгебра афрагма). Далее указывается один словообразующий символ, заключенный в скобки и тем самым превращенный в первую группу нашего регулярного выражения. После этого указывается словообразующий символ, снабженный квантификатором «*»; этот квантификатор означает, что предшествующий элемент регулярного выражения может повторяться 0 или более раз. Наконец, указывается специальная директива \1, означающая, что на данной позиции должен находится текст, совпадающий с текстом ранее найденной первой группы.


Приведенное решение имеет два недочета. Первый недочет очевиден: при подобном поиске естественно было бы включить в список найденных слов и слово «Каучук», несмотря на то что оно начинается с заглавной буквы. Для исправления этого недочета достаточно в методе Matches указать в качестве последнего параметра соответствующую опцию поиска:

foreach a: match in Regex.Matches(s, '\b(\w)\w*\1\b', RegexOptions.IgnoreCase) do

Write(a.Value, ' ');

Параметр, задающий опции поиска, можно указывать в любом из рассмотренных ранее классовых методов класса Regex, а также в конструкторе данного класса. Опции поиска можно также задать непосредственно в регулярном выражении, используя специальную директиву:

foreach a: match in Regex.Matches(s, '(?i)\b(\w)\w*\1\b') do

Write(a.Value, ' ');

Второй недочет приведенного решения менее очевиден. Указанное регулярное выражение не будет находить однобуквенные слова (такие как «а», «в», «и» и т. д.), хотя они тоже начинаются и оканчиваются одной и той же буквой. Для того чтобы в результирующий список включались и однобуквенные слова, необходимо предусмотреть их специальную обработку в регулярном выражении: слово должно или удовлетворять ранее приведенному варианту регулярного выражения, или являться однобуквенным. Для связки или в языке регулярных выражений имеется специальная операция |. Простейшая модификация нашего исходного регулярного выражения будет выглядеть следующим образом:

(?i)\b(\w)\w*\1\b|\b\w\b

Нетрудно заметить, что в начале и конце любого из двух вариантов содержатся директивы \b. Чтобы не указывать эту пару директив дважды, ее можно вынести за знак операции |:

(?i)\b((\w)\w*\2|\w)\b

Обратите внимание на то, что теперь группа (\w) стала второй по счету группой регулярного выражения, поэтому необходимо соответствующим образом откорректировать директиву обращения к этой группе.

Следующий пример демонстрирует дополнительные возможности, которые предоставляет использование групп при замене подстрок. Предположим, что имеется строка, содержащая несколько дат в «американском» формате: «месяц/день/год», причем в качестве разделителя может использоваться как косая черта «/», так и точка «.». Значения месяцев и дней могут указываться одной или двумя цифрами, а значения лет - четырьмя цифрами. Будем считать, что все даты в указанном формате, содержащиеся в исходной строке, являются правильными и отделяются от предшествующих и последующих слов по крайней мере одним пробелом (либо находятся в начале или конце строки). Требуется преобразовать все подобные даты к «российскому» формату «день/месяц/год», сохранив тот же разделитель, который использовался в исходной дате.


Чтобы получить наиболее простой вариант решения данной задачи, нам необходимо познакомиться еще с тремя элементами языка регулярных выражений. Первые два из них относятся к директивам, определяющим множество символов (подобным ранее рассмотренной директиве \w): это директива \d, означающая любую десятичную цифру, и «универсальная» директива для определения множества, имеющая вид [символы], где в квадратных скобках указываются все символы, допустимые для данного множества (более подробное описание данной директивы и ее вариантов приводится в третьей части статьи).

Третий элемент относится к подстановкам, используемым в выражениях замены: это подстановка вида $N, где N - некоторое положительное целое число. Данная подстановка заменяется на группу номер N, содержащуюся в текущем найденном вхождении (или на пустую строку, если группа номер N в текущем вхождении отсутствует).

С использованием этих новых средств языка регулярных выражений решение задачи примет следующий вид:

Writeln(Regex.Replace(s, '\b(\d{1,2})([./])(\d{1,2})\2(\d{4})\b', '$3$2$1$2$4'));

Если строка s равна '12/30/1998  1.3.2001  обычный текст  10/2/2002', то в результате выполнения указанного оператора на экран будет выведена строка

30/12/1998  3.1.2001  обычный текст  2/10/2002

В использованном регулярном выражении были определены четыре группы: первая связана с месяцем, вторая - с символом-разделителем, третья - с днем и четвертая - с годом. Все эти группы, только в другом порядке, используются в третьем параметре, определяющем выражение замены.
Завершая обсуждение возможностей, связанных с группами, отметим, что в классе Match имеется свойство Groups типа GroupCollection, доступное только для чтения и позволяющее получить информацию обо всех группах, связанных с найденным вхождением (группы индексируются от 0, причем группа номер 0 совпадает со всем найденным вхождением). 

ЗАКЛЮЧЕНИЕ

В первую очередь хотелось бы отметить легкий синтаксис языка. Для освоения Паскаля необходимо выучить небольшое число базовых понятий. К тому же, любая утилита, разработанная на этом языке, будет легко читаться. 
Компилятор Паскаля имеет невысокие аппаратные и системные требования. Это же можно сказать и о софте, который будет выполнен с помощью этого языка программирования. 

Визуальная среда Delphi помогает создать за короткий промежуток времени качественную оконную утилиту, не напрягая голову разработчика лишними проблемами исполнения кода на чистом WinAPI.
При работе с Паскалем очень редко необходимы вставки ассемблера. В основном весь софт подготовлен и готов к работе. Также, стоит отметить открытый исходный код, который доступен к редактированию каждому умельцу.


Основным компонентом системы программирования Turbo Pascal является компилятор языка. Кроме него в систему входят средства для создания софта, его редактирования и средства для поиска ошибок, так называемые инструменты отладки. 

Все эти компоненты в совокупности создают единую среду разработчика, в которой программист работает и создает приложения.

Недостатки Паскаль

Несмотря на все достоинства, есть у него и слабые стороны. Их не так много, но они могут оттолкнуть современных программистов:

  1. Этот язык создали в 60-х годах. Соответственно, в наше время он считается уже устаревшим.
  2. Используется в основном только в странах бывшего Советского Союза. 
  3. В действительности очень мало реального ПО. 

СПИСОК ЛИТЕРАТУРЫ

1. PASCAL-XSC. Язык численного программирования / Р. Клатте и др. - М.: НИЦ «Регулярная и хаотическая динамика», 2016. - 352 c.

2. Абрамов, В. Г. Введение в язык паскаль / В.Г. Абрамов, Н.П. Трифонов, Г.Н. Трифонова. - М.: Наука, 2013. - 320 c.

3. Андреева, Т. А. Программирование на языке Pascal / Т.А. Андреева. - М.: Интернет-университет информационных технологий, Бином. Лаборатория знаний, 2013. - 240 c.

4. Арсак, Ж. Программирование игр и головоломок / Ж. Арсак. - М.: Главная редакция физико-математической литературы издательства «Наука», 2016. - 224 c.

5. Аручиди, Н. А. Компьютер в работе бухгалтера / Н.А. Аручиди. - М.: Феникс, 2016. - 368 c.

6. Гагарина, Л. Г. Компьютерный практикум для менеджеров / Л.Г. Гагарина, Е.М. Портнов, И.С. Холод. - М.: Финансы и статистика, 2014. - 352 c.

7. Грызлов, В. И. Турбо Паскаль 7.0 / В.И. Грызлов, Т.П. Грызлова. - М.: ДМК, 2016. - 416 c.

8. Епанешников, А. М. Программирование в среде Turbo Pascal 7.0 / А.М. Епанешников, В.А. Епанешников. - М.: Диалог-Мифи, 2011. - 368 c.

9. Зеленяк, О. П. Современный задачник по Турбо Паскалю / О.П. Зеленяк. - М.: ДМК Пресс, 2014. - 312 c.

10. Карпов, Александр Постановка и автоматизация управленческого учета / Александр Карпов. - М.: Результат и качество, 2011. - 504 c.

11. Касторнова, В. А. Структуры данных и алгоритмы их обработки на языке программирования Паскаль / В.А. Касторнова. - М.: БХВ-Петербург, 2016. - 304 c.

12. Кашаев, С. М. Паскаль для школьников. Подготовка к ЕГЭ (+ CD-ROM) / С.М. Кашаев, Л.В. Шерстнева. - М.: БХВ-Петербург, 2011. - 336 c.

13. Кашаев, С. М. Паскаль для школьников. Подготовка к ЕГЭ / С.М. Кашаев, Л.В. Шерстнева. - М.: БХВ-Петербург, 2011. - 336 c.

14. Кетков, А. Практика программирования Бейсик, Си, Паскаль / А. Кетков, Ю. Кетков. - М.: БХВ-Петербург, 2011. - 480 c.