Строки: посимвольная обработка, length, copy, pos

Урок учит обрабатывать текст: обращаться к отдельным символам строки и пользоваться функциями length, copy, pos для поиска и выделения подстрок.

Строка (string) — это последовательность символов, к каждому из которых можно обратиться по его номеру, как к элементу массива.

Строка как последовательность символов

Мы уже знаем тип string для хранения текста. Но строка — это не монолит, а цепочка символов, и с ней можно работать гораздо тоньше: посчитать буквы, найти слово, вырезать кусок, проверить каждый символ. Текстовая обработка — огромная часть программирования: проверка паролей, разбор данных, шифрование, поиск. Сегодня разберём базовые инструменты.

Ключевая идея: к строке можно обращаться, как к массиву символов. В Паскале символы строки нумеруются с 1: первый символ — s[1], второй — s[2] и так далее.

Обращение к символам и длина строки

Функция length(s) возвращает количество символов в строке. В связке с циклом она позволяет пройти строку по буквам:

var
  s: string;
  i: integer;
begin
  s := 'Привет';
  writeln('Длина строки: ', length(s));   // 6
  for i := 1 to length(s) do
    writeln(i, ': ', s[i]);               // печатаем каждый символ
end.

Цикл for i := 1 to length(s) — классический способ перебрать строку посимвольно. Внутри s[i] — это i-й символ (тип char). Можно не только читать, но и менять символы: s[1] := 'п'. Запустите аналог на Python (там символы нумеруются с 0):

s = 'Привет'
print('Длина строки:', len(s))
for i in range(len(s)):
    print(i + 1, ':', s[i])   # +1, чтобы нумерация была как в Паскале

Вывод:

Длина строки: 6
1 : П
2 : р
3 : и
4 : в
5 : е
6 : т

Подсчёт символов

Посимвольный перебор открывает массу задач. Посчитаем, например, сколько раз в строке встречается буква «а». Шаблон тот же, что для подсчёта в массиве: счётчик, цикл, проверка условия:

s = 'абракадабра'
count = 0
for i in range(len(s)):
    if s[i] == 'а':
        count = count + 1
print('Букв "а":', count)

Вывод:

Букв "а": 5

Функция pos: поиск подстроки

Функция pos(подстрока, строка) ищет первое вхождение подстроки и возвращает номер позиции, с которой она начинается. Если подстрока не найдена — возвращает 0:

var
  s: string;
begin
  s := 'абракадабра';
  writeln(pos('бра', s));   // 2 — 'бра' начинается со 2-й позиции
  writeln(pos('xyz', s));   // 0 — не найдено
end.

Результат 0 при отсутствии подстроки — удобный признак: if pos('@', email) = 0 then writeln('Не похоже на e-mail'). Это основа любой проверки «содержит ли текст...». Аналог на Python (метод find возвращает -1 при отсутствии, а позицию — с 0, поэтому прибавим 1):

s = 'абракадабра'
p = s.find('бра')
print(p + 1 if p != -1 else 0)   # позиция как в Паскале
print(s.find('xyz') + 1)          # -1 + 1 = 0, не найдено

Вывод:

2
0

Функция copy: вырезать подстроку

Функция copy(s, начало, количество) возвращает кусок строки: количество символов, начиная с позиции начало. Сама строка s при этом не меняется:

var
  s: string;
begin
  s := 'программирование';
  writeln(copy(s, 1, 7));   // 'програм' — 7 символов с 1-й позиции
  writeln(copy(s, 8, 4));   // 'миро' — 4 символа с 8-й позиции
end.
s = 'программирование'
print(s[0:7])    # copy(s,1,7): символы с 1 по 7
print(s[7:11])   # copy(s,8,4): 4 символа начиная с 8-го

Вывод:

програм
миро

Сочетая pos и copy, можно решать настоящие задачи: найти позицию пробела через pos(' ', s) и вырезать через copy первое слово до него. Это типичный приём разбора текста.

Процедуры delete и insert

В отличие от функций выше, эти процедуры изменяют саму строку:

  • delete(s, начало, количество) — удаляет из s заданное число символов с указанной позиции.
  • insert(что, s, куда) — вставляет подстроку в s в указанную позицию.
var
  s: string;
begin
  s := 'Привет, мир!';
  delete(s, 1, 8);             // удалить 8 символов с начала -> 'мир!'
  insert('новый ', s, 1);      // вставить в начало -> 'новый мир!'
  writeln(s);
end.

Для склейки строк, напомним, используется простой +: 'Привет, ' + name. А для преобразования числа в строку и обратно есть функции IntToStr(число) и StrToInt(строка) — они пригодятся, когда нужно «склеить» число с текстом или разобрать введённый текст как число.

Попробуй сам

Напишите программу, которая проверяет, является ли строка палиндромом (читается одинаково слева направо и справа налево, например «казак»). Идея: сравнивать s[i] с симметричным символом с конца. Проверьте на Python:

s = 'казак'
is_palindrome = True
n = len(s)
for i in range(n // 2):
    if s[i] != s[n - 1 - i]:
        is_palindrome = False
        break
print('Палиндром' if is_palindrome else 'Не палиндром')

Вывод:

Палиндром

Частые ошибки

  • Нумерация символов с 0. В Паскале символы строки нумеруются с 1, поэтому первый — s[1]. Привычка из Python (с 0) приводит к ошибкам.
  • Путают copy и pos. pos ищет и возвращает позицию (число), copy вырезает и возвращает подстроку (текст).
  • Считают, что copy меняет строку. copy только возвращает кусок, не трогая исходную строку. Изменяют строку delete и insert.
  • Не проверяют результат pos на 0. Если подстроки нет, pos вернёт 0 — это нужно учитывать, иначе copy с нулевой позицией даст неверный результат.

Итоги

  • Строка — последовательность символов; в Паскале они нумеруются с 1, доступ через s[i].
  • length(s) даёт длину; цикл for i := 1 to length(s) перебирает строку посимвольно.
  • pos(подстрока, s) возвращает позицию первого вхождения или 0, если не найдено.
  • copy(s, начало, кол-во) вырезает подстроку, не меняя оригинал; delete и insert изменяют строку.
  • Сочетание pos + copy — основа разбора текста; IntToStr/StrToInt переводят между числом и строкой.
Проверьте себя
1. С какого номера начинается нумерация символов строки в Паскале?
AС 0
BС 1
CС -1
DЗависит от длины строки
2. Что вернёт функция pos('бра', 'абракадабра')?
A0
B2
C3
D'бра'
3. Чем функция copy отличается от процедуры delete?
Acopy возвращает подстроку, не меняя оригинал; delete удаляет символы из строки
BОни делают одно и то же
Ccopy удаляет символы, а delete вставляет
Dcopy работает только с числами
Поддержать проект