Занятие 8. Pascal abc.net: Строки / Регулярные выражения / Файлы

Знакомство с понятием регулярного выражения. Работа со строками и регулярными выражениями в Паскаль abc.net

Символы

c: char;
...
c:='a';
begin
var c: char;
c:='a';
Println(c.IsDigit); // число ли - False 
Println(c.IsLetter); // буква ли - True 
Println(c.IsLower); // строчная ли - True
Println(c.IsUpper); // прописная ли - False 
end.

Строки

s: string;
...
s:='abc';
begin
var s: string;
s:='Abc';
Println(s.ToLower); // abc 
Println(s.ToUpper); // ABC 
end.

Срезы для строк:

begin
var s: string;
s:='12345678';
Println(s[3:6]); // 345 
Println(s[::-1]); // 87654321 
end.

Методы:
Преобразования строка <-> число:

begin
var s: string;
s:='12345678';
var i:=1;
Println(i.ToString); // строка '1'
Println(s.ToInteger); // число 12345678 
Println(s.ToReal); // число 12345678 
end.

ИЛИ

begin
var s: string;
s:='12345678';
var i:=1;
Println(integer.TryParse(s,i)); // можно ли преобразовать строку s в число - True 
end.

Преобразование строки в массив слов:

begin
var s:='каждый охотник желает знать, где сидит фазан';
var ss:=s.ToWords.Println; // каждый охотник желает знать, где сидит фазан
ss.Sorted.Println // где желает знать, каждый охотник сидит фазан
end.

Добавляем разделитель:

begin
var s:='каждый охотник желает знать, где сидит фазан';
var ss:=s.ToWords.Println; // каждый охотник желает знать, где сидит фазан
ss.JoinIntoString('!').Println // каждый!охотник!желает!знать,!где!сидит!фазан
end.
  • CountOf — количество вхождений
  • 'мама мыла раму'.CountOf('м').Print; // 4
  • Contains — содержит ли (логическая)
  • 'мама мыла раму'.Contains('б').Print; // False
  • IndexOf — индекс искомого вхождения
  • 'hello world'.IndexOf('w').Print; // 6
  • Remove — удаление вхождения
  • 'hello world'.Remove(' ').Print; // helloworld
  • Replace — замена вхождений символа на другой символ
  • 'hello world'.Replace('l','L').Print; // heLLo worLd

    и другие…

    Запросы LINQ со строками

    * LINQ (Language Integrated Query) — язык интегрированных запросов

  • Where — Фильтрация массива (последовательности) с условием
  • var sArr:=Arr('aab','bcd','efg');
    sArr.Where(w->w.Contains('b')).Print; // aab bcd
    sArr.Where(w->w.CountOf('a')=2).Print; // aab

    Пример: удалить все буквы «ж«:

    begin
    var s:='каждый охотник желает знать, где сидит фазан';
    s:=s.Where(c -> c<>'ж').JoinIntoString;
    print(s); // кадый охотник елает знать, где сидит фазан 
    end.

    При работе со строками можно использовать любой метод последовательности

    Язык регулярных выражений

    Язык регулярных выражений — это язык шаблонов, расширенные операции поиска и замены для строк.

    Основной цикл:

    s := 'red  green  gray blue';
    foreach var m in s.Matches('\w+') do
      Print(m.Value, m.Index);

    Т.е. m: Match включает m.Value, m.Index
    Опции регулярных выражений:

    s := 'AБракадабРА';
    s.Matches('бра', RegexOptions.IgnoreCase)

    Примеры регулярных выражений:
    ‘кот|кит’ ‘к[ио]т’ ‘к[а-я]т’ ‘ко+т’ ‘кор?т’ ‘к.т’ ‘к\.т’ ‘к.*т’
    ‘ко{3}т’ ‘ко{2,4}т’ ‘ко[^ъыь]т’ ‘\b кот\b’

    Управляющие символы и их запись в регулярных выражениях:
    \ * + ? | { [ ( ) ^ $ . #
    Они экранируются дополнительным \

    Квантификаторы:
    * — 0 или более повторений
    + — 1 или более повторений
    ? — 0 или 1 повторение
    {N} — ровно N повторений
    {N,} — не менее N повторений
    {N,M} — от N до M повторений

    Директивы нулевой длины:
    ^ — начало строки
    $ — конец строки
    \b — позиция на границе слова

    Классы символов:
    [abcd] — один из символов, указанных в списке
    [^abcd] — любой из символов, кроме тех, которые указаны в списке
    [a-d] — один из символов, лежащих в указанном диапазоне
    [^a-d] — любой из символов, кроме тех, которые лежат в указанном диапазоне
    \d — десятичная цифра: [0-9]
    \D — любой символ, кроме десятичной цифры
    \w — буква, цифра или символ подчеркивания
    \W — любой символ, не являющийся словообразующим;
    \s — пробельный символ, т. е. [ \t\r\n];
    \S — любой непробельный символ;
    . — любой символ

    Группы:

    s := ' prepod@sfedu.ru   prepod2@sfedu.ru ';
    foreach var m in s.Matches('(\w+)@(\w+).(\w+)') do
      Println(m.Groups[0], m.Groups[1], m.Groups[2], m.Groups[3]); 
    s.Matches('(т[оае])\1*')

    Замена с помощью регулярного выражения:

    s.Replace('\b\w+\b', '<$0>')
    s := s.Replace('\w+',m->m.Value.ToUpper);
    s := s.Replace('\w+',m->m.Value+'('+m.Length+')')
    s := '10+2=12';
    s.Replace('\d+', '<$0>') // <10>+<2>=<12>
    s.Replace('\d+', m -> (m.Value.ToInteger*2).ToString) // 20+4=24
     
    s := ' prepod@sfedu.ru   prepod2@sfedu.ru ';
    s.Replace('(\w+)@(\w+).(\w+)', '$1-$2-$3')

    Файлы

    • текстовые файлы : Text
    • типизированные файлы : file of ...
    • бестиповые (двоичные файлы) : file

    Прежний стиль работы:

    var f:file of integer;
    begin
    reset(f,'a.dat');
    write(f,1,3);
    read (f,x,y);
    close(f);

    Новый стиль работы:

    var f:=OpenFile&<integer>('a.dat');
    f.Wriet(1,3);
    Read(f,x,y);
    Close(f);

    Символ & необходим для снятия значения операции меньше <
    Файл из элементов одного типа можно воспринимать, как последовательность:

    ReadElements&<integer>('a.dat');
     
    ...
    foreach var i in ReadElements&<integer>('a.dat') do
    ...

    Для текстовых файлов:

    var f:=OpenRead('a.txt');
    var f:=OpenWrite('a.txt');
     
    f.ReadLnString
     
    while not f.EOF do
      begin
      var s:=f.ReadLnString;
      Print(s)
      end;
    f.close;

    ReadLines('a.txt') - открытие на чтение, значения - последовательность строк.

    Можно выполнять функции последовательностей:
    ReadLines('a.txt').Skip(1);

    Решение задач

    ?Пример 1: Вывести все слова из файла.

    Выполнение:

    begin
    var a:=ReadLines('in.txt');
    //var a:='dfgdg  argag asfa tyru';
    foreach var w in a do
    begin
      var ww:=w.Matches('\w+');
      writeln(ww);
    end;
    end.
    Пример 2: Вывести все слова длиной в 3 символа

    Выполнение:

    begin
    var a:=ReadLines('in.txt');
    foreach var w in a do
    begin
      var ww:=w.Matches('\b\w{3}\b');
      ww.Println;
    end;
    end.
    Пример 3: Вывести все слова, длина которых составляет 3,4 или 5 символов

    Выполнение:

    begin
    var a:=ReadLines('in.txt');
    foreach var w in a do
    begin
     var ww:=w.Matches('\b\w{3,5}\b');
      ww.Println;
    end;
    end.
    Пример 4: Вывести все слова, начинающиеся на 'с' и заканчивающиеся на 'а'. Проверьте, что не выводятся подстроки.

    Выполнение:

    begin
    var a:=ReadLines('in.txt');
    foreach var w in a do
    begin
     var ww:=w.Matches('\bс\w+а\b');
      ww.Println;
    end;
    end.
    Пример 5: Вывести все числа

    Выполнение:

    begin
    var a:=ReadLines('in.txt');
    foreach var w in a do
    begin
     var ww:=w.Matches('\d');
      ww.Println;
    end;
    end.
    Пример 6: Вывести все слова, в которых первый и последний символы совпадают. Учесть однобуквенные.

    Выполнение:

     
    Пример 7: Замените все даты в американском формате (с . или /) на привычный формат с . в качестве разделителя и номером дня недели первым

    Выполнение:

    begin
    var a:=ReadLines('in.txt');
    foreach var w in a do
    begin
      var ww:=w.Replace('(\d{1,2})[./](\d{1,2})[./](\d{2,4})','$2.$1.$3');
      ww.Println;
    end;
    end.
    Пример 8: Найдите числа с запятой или пробелом, в качестве разделителя разрядов

    Выполнение:

    begin
    var a:=ReadLines('in.txt');
    foreach var w in a do
    begin
     var ww:=w.Matches('\b\d+[, ]\d+\b');
      ww.Println;
    end;
    end.
    Пример 9: Выделить тегом strong повторяющиеся подряд слова. (например, "все все - все <strong>все</strong>")

    Выполнение:

     
    Пример 10: Преобразовать текст, обрамленный в две звездочки (**), в полужирное начертание (тег bold)

    Выполнение:

    begin
    var a:=ReadLines('inMD.txt');
    foreach var w in a do
    begin
      var ww:=w.Replace('\*\*(\b\w+\b)\*\*','<bold>$1<bold>');
      ww.Println;
    end;
    end.
    Пример 11: Выбрать IPv4 адреса

    Выполнение:

    begin
    var a:=ReadLines('in.txt');
    foreach var w in a do
    begin
     var ww:=w.Matches('\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b');
      ww.Println;
    end;
    end.
    Пример 12: Напишите преобразование обозначений MarkDown в соответствующие теги htlm

    Выполнение: