Показаны различия между двумя версиями страницы.
— |
cp:obx-filter [2021/06/19 15:22] (текущий) rbv создано |
||
---|---|---|---|
Строка 1: | Строка 1: | ||
+ | ====== Фильтрация и обработка текста ====== | ||
+ | Пример фильтрации текста при помощи сканера (TextMappers.Scanner) и вывода результата в новое окно. | ||
+ | |||
+ | ===== Задача ===== | ||
+ | |||
+ | Подсчитать количество целых чисел и их сумму в выделенном тексте активного текстового документа (АТД). Результаты показать в новом документе. | ||
+ | |||
+ | ===== Алгоритм ===== | ||
+ | ==== Основной ==== | ||
+ | |||
+ | Построение алгоритма методом пошагового уточнения начинается с одного единственного шага " | ||
+ | |||
+ | <code componentpascal> | ||
+ | Обработать АТД | ||
+ | Вывести результаты | ||
+ | </ | ||
+ | |||
+ | Обработка АТД, по условию задачи, | ||
+ | |||
+ | <code componentpascal> | ||
+ | Если есть АТД, то | ||
+ | Получить АТД; | ||
+ | Обработать выделенный текст; | ||
+ | Вывести результаты | ||
+ | Конец | ||
+ | </ | ||
+ | |||
+ | Соображения касательно обработки выделенного текста аналогичные: | ||
+ | |||
+ | <code componentpascal> | ||
+ | Если есть АТД, то | ||
+ | Получить АТД; | ||
+ | Если есть выделение, | ||
+ | Получить границы выделения; | ||
+ | Обработать текст пределах этих границ; | ||
+ | Вывести результаты | ||
+ | Конец | ||
+ | Конец | ||
+ | </ | ||
+ | |||
+ | ==== Обработка участка текста документа ==== | ||
+ | |||
+ | Обработка текста документа в заданном диапазоне выполняется на основе стандартной схемы цикла - полного прохода по элементам последовательности с фильтрацией: | ||
+ | |||
+ | <code componentpascal> | ||
+ | Получить первый элемент; | ||
+ | Пока элемент получен, | ||
+ | Если элемент удовлетворяет условию отбора (проходит через фильтр), | ||
+ | Обработать элемент | ||
+ | Конец; | ||
+ | Получить следующий элемент | ||
+ | Конец | ||
+ | </ | ||
+ | |||
+ | В нашем случае последовательность представляет собой значения различных типов (целые, | ||
+ | |||
+ | ==== Вывод результатов ==== | ||
+ | |||
+ | Вывод результатов - обычный линейный алгоритм: | ||
+ | <code componentpascal> | ||
+ | Создать новый текстовый документ; | ||
+ | Записать количество чисел; | ||
+ | Записать сумму чисел; | ||
+ | Показать документ в новом окне | ||
+ | </ | ||
+ | |||
+ | ===== Реализация ===== | ||
+ | |||
+ | ==== Вариант 1 ==== | ||
+ | |||
+ | <code componentpascal> | ||
+ | MODULE ExamplesFilterInText; | ||
+ | |||
+ | IMPORT TextControllers, | ||
+ | |||
+ | PROCEDURE GetInts*; | ||
+ | VAR | ||
+ | c: TextControllers.Controller; | ||
+ | atd, sel: TextModels.Model; | ||
+ | beg, end: INTEGER; | ||
+ | num: INTEGER; | ||
+ | sum: INTEGER; | ||
+ | |||
+ | PROCEDURE ProcessText; | ||
+ | VAR | ||
+ | s: TextMappers.Scanner; | ||
+ | BEGIN | ||
+ | s.ConnectTo(sel); | ||
+ | |||
+ | (* Читаем и обрабатываем целые из последовательности значений в тексте *) | ||
+ | sum := 0; num := 0; | ||
+ | s.Scan; | ||
+ | (* Пока получен (не конец текста) *) | ||
+ | WHILE s.type # TextMappers.eot DO | ||
+ | IF s.type = TextMappers.int THEN (* отбираем целые *) | ||
+ | (* Обрабатываем *) | ||
+ | sum := sum + s.int; | ||
+ | INC(num) | ||
+ | END; | ||
+ | s.Scan | ||
+ | END | ||
+ | END ProcessText; | ||
+ | |||
+ | PROCEDURE PrintResults; | ||
+ | VAR | ||
+ | t: TextModels.Model; | ||
+ | f: TextMappers.Formatter; | ||
+ | BEGIN | ||
+ | t := TextModels.dir.New(); | ||
+ | |||
+ | (* Пишем результат *) | ||
+ | f.ConnectTo(t); | ||
+ | f.WriteString(" | ||
+ | f.WriteString(" | ||
+ | |||
+ | Views.OpenView(TextViews.dir.New(t)) | ||
+ | END PrintResults; | ||
+ | |||
+ | BEGIN | ||
+ | c := TextControllers.Focus(); | ||
+ | IF c # NIL THEN (* если есть контроллер (значит есть и АТД) *) | ||
+ | atd := c.text; | ||
+ | IF c.HasSelection() THEN (* если есть выделение *) | ||
+ | c.GetSelection(beg, | ||
+ | sel := TextModels.dir.New(); | ||
+ | sel.InsertCopy(0, | ||
+ | ProcessText; | ||
+ | PrintResults | ||
+ | END | ||
+ | END | ||
+ | END GetInts; | ||
+ | |||
+ | END ExamplesFilterInText. | ||
+ | </ | ||
+ | |||
+ | ==== Вариант 2 ==== | ||
+ | |||
+ | <code componentpascal> | ||
+ | MODULE ExamplesFilterInText; | ||
+ | IMPORT TextControllers, | ||
+ | |||
+ | PROCEDURE GetInts*; | ||
+ | VAR | ||
+ | s: TextMappers.Scanner; | ||
+ | beg, end: INTEGER; | ||
+ | sum, num: INTEGER; | ||
+ | |||
+ | PROCEDURE ConnectScanner; | ||
+ | VAR | ||
+ | c: TextControllers.Controller; | ||
+ | BEGIN | ||
+ | s.ConnectTo(NIL); | ||
+ | |||
+ | c := TextControllers.Focus(); | ||
+ | IF (c # NIL) & c.HasSelection() THEN | ||
+ | c.GetSelection(beg, | ||
+ | |||
+ | s.ConnectTo(c.text); | ||
+ | ASSERT(s.rider # NIL) | ||
+ | END | ||
+ | END ConnectScanner; | ||
+ | |||
+ | PROCEDURE PrintSum; | ||
+ | VAR | ||
+ | f: TextMappers.Formatter; | ||
+ | t: TextModels.Model; | ||
+ | BEGIN | ||
+ | t := TextModels.dir.New(); | ||
+ | f.ConnectTo(t); | ||
+ | |||
+ | f.WriteString(" | ||
+ | f.WriteInt(num); | ||
+ | f.WriteLn; | ||
+ | |||
+ | f.WriteString(" | ||
+ | f.WriteInt(sum); | ||
+ | f.WriteLn; | ||
+ | |||
+ | Views.OpenView(TextViews.dir.New(t)) | ||
+ | END PrintSum; | ||
+ | |||
+ | BEGIN | ||
+ | ConnectScanner; | ||
+ | IF s.rider # NIL THEN | ||
+ | sum := 0; | ||
+ | num := 0; | ||
+ | |||
+ | s.SetPos(beg); | ||
+ | s.Scan; | ||
+ | WHILE (s.type # TextMappers.eot) & (s.Pos() - 1 <= end) DO | ||
+ | IF s.type = TextMappers.int THEN | ||
+ | INC(sum, s.int); | ||
+ | INC(num) | ||
+ | END; | ||
+ | |||
+ | s.Scan | ||
+ | END; | ||
+ | |||
+ | PrintSum | ||
+ | END | ||
+ | END GetInts; | ||
+ | |||
+ | END ExamplesFilterInText. | ||
+ | |||
+ | (* | ||
+ | @ExamplesFilterInText.GetInts | ||
+ | |||
+ | 1 2 3 4 5 6 7 8 9 | ||
+ | Mister Jack paid 99.99$ for 10 balls | ||
+ | 11 12 | ||
+ | *) | ||
+ | </ | ||
+ | |||
+ | // |