Лабораторная работа №4 - Регулярные выражения. Разные функции. Формы, качество кода и современные подходы в web-разработке. Асинхронность и интеграция с внешними сервисами
1. Теория
1.0. Цель работы
Сформировать у обучающегося устойчивые навыки:
- применения регулярных выражений (RegExp) для поиска, извлечения и валидации пользовательского ввода;
- разработки форм и клиентской валидации (обязательность, формат, диапазоны, сообщения об ошибках);
- использования встроенных и пользовательских функций обработки данных (нормализация, фильтрация, преобразования, проверки);
- реализации асинхронного получения данных (
fetch,Promise,async/await), обработки JSON и контроля ошибок (сетевые ошибки, неверный формат, пустой ответ, статус-коды); - соблюдения качества кода: читаемость, модульность, предсказуемость, отсутствие дублирования, “современный подход” (чистые функции, единственный источник истины, аккуратная работа с состоянием UI).
1.1. Место лабораторной работы №4 в проекте семестра
Лабораторная работа №1 создала основу:
- репозиторий GitHub;
- структура проекта (
index.html,style.css,script.js,README.md,passport.md); - простая верстка под предметную область;
- проверка подключения JavaScript;
- формирование контекста проекта через паспорт предметной области.
Лабораторная работа №2 развила проект:
- добавила алгоритмическое ядро;
- ввела набор данных предметной области;
- закрепила работу с
const/let, типами данных, операторами, условиями и циклами; - добавила первичную демонстрацию результатов (консоль + блок вывода на странице);
- подготовила основу для перехода к DOM и пользовательскому интерфейсу.
Лабораторная работа №3 сделала следующий шаг:
- связала алгоритмическое ядро с интерфейсом через DOM;
- закрепила принцип: данные → обработка → отображение;
- ввела архитектурную дисциплину: данные в
data.js, логика вlogic.js, UI-слой вscript.js; - реализовала интерактивный список и базовые сценарии управления UI.
Лабораторная работа №4 делает проект “похожим на реальный web-продукт”:
- появляется форма для создания/редактирования записей;
- добавляется валидация (в том числе на базе регулярных выражений);
- появляется асинхронная интеграция с внешним сервисом (получение данных по сети), обработка JSON и ошибок;
- укрепляется инженерный стиль: качество кода, повторное использование функций, отсутствие копипаста, единая точка принятия решений (валидация и нормализация вынесены в функции).
1.2. Регулярные выражения (RegExp): что это и зачем
Регулярные выражения — это способ описания шаблонов строк. Они используются, когда необходимо:
- проверить, что строка соответствует формату (валидация);
- найти фрагменты текста;
- извлечь данные (например, id, дату, номер, код);
- нормализовать ввод (удалить лишние пробелы, привести формат к единому виду).
В JavaScript регулярные выражения создаются:
const re1 = /abc/; // литерал
const re2 = new RegExp("abc"); // конструктор
1.3. Базовые методы строк и RegExp: test, match, replace
Проверка соответствия (валидация):
const re = /^\d+$/;
console.log(re.test("123")); // true
console.log(re.test("12a")); // false
Извлечение совпадений:
const text = "id=25; id=30";
const ids = text.match(/\d+/g); // ["25", "30"]
Нормализация (замена):
const raw = " Иванов Иван ";
const clean = raw.replace(/\s+/g, " ").trim();
console.log(clean); // "Иванов Иван"
1.4. Валидация ввода с помощью RegExp: практический смысл
Валидация — это проверка корректности данных до того, как программа примет их как “истину”.
Типовые проверки:
- обязательность поля;
- длина (
min/max); - формат (дата
YYYY-MM-DD, “код”, “номер”, “email” и т.д.); - допустимые символы;
- диапазон чисел.
Пример формата даты:
const reDate = /^\d{4}-\d{2}-\d{2}$/;
Важно понимать: регулярное выражение проверяет формат, но не всегда проверяет смысл (например, 2026-99-99 формально подходит под шаблон). Поэтому в инженерном коде часто применяется “двухэтапная проверка”:
- формат RegExp;
- смысловая проверка (диапазоны, Date.parse, сравнение дат и т.д.).
1.5. Формы в web: submit, preventDefault, чтение значений
Форма в HTML — стандартный способ пользовательского ввода. В этой лабораторной работе форма применяется для создания/редактирования записи предметной области.
Типовая схема:
- пользователь вводит данные;
- нажимает “Сохранить”;
- происходит событие
submit; - JavaScript перехватывает
submit, делаетpreventDefault(), валидирует ввод, затем обновляет данные и UI.
Пример:
formEl.addEventListener("submit", (e) => {
e.preventDefault();
// 1) чтение значений
// 2) валидация
// 3) обновление массива items
// 4) renderList(...)
});
1.6. Сообщения об ошибках и качество UX валидации
Минимальные правила хорошей валидации:
- ошибка должна быть конкретной (“Некорректная дата: ожидается YYYY-MM-DD”);
- ошибка должна быть привязана к форме/полю;
- если ошибок несколько — показывать список или показывать первую ошибку;
- успешный ввод должен приводить к понятному результату (запись добавилась, список обновился, форма очистилась).
Для лабораторной работы достаточно использовать:
- блок
#messageдля сообщений; - (рекомендуется) отдельный блок
#formErrorsрядом с формой.
1.7. Асинхронность: Promise, async/await, сетевые запросы fetch
Асинхронный код нужен, когда результат появляется не сразу (например, при запросе по сети).
fetch(url) возвращает Promise, который выполняется позже.
Пример на async/await:
async function loadSomething() {
const resp = await fetch("https://example.com/data.json");
const data = await resp.json();
return data;
}
1.8. Обработка ошибок при fetch: статус-коды, try/catch, защита от “плохого” JSON
Сетевой код обязан учитывать:
- запрос может не выполниться (нет сети);
- сервер может вернуть код ошибки (404, 500);
- сервер может вернуть не-JSON или “сломанный” JSON;
- ответ может быть пустым.
Базовый надежный шаблон:
async function safeFetchJson(url) {
let resp;
try {
resp = await fetch(url);
} catch (err) {
return { ok: false, error: "Сетевая ошибка", details: String(err) };
}
if (!resp.ok) {
return { ok: false, error: `HTTP ошибка: ${resp.status}`, details: resp.statusText };
}
let data;
try {
data = await resp.json();
} catch (err) {
return { ok: false, error: "Ошибка JSON", details: String(err) };
}
return { ok: true, data };
}
1.9. Качество кода и современные подходы
Минимальные инженерные правила для этой лабораторной работы:
- валидация и нормализация вынесены в функции (не писать проверки прямо внутри обработчика формы);
- UI-слой не содержит дублирования логики (обработчики вызывают функции
logic.js); - функции делают одну задачу и имеют предсказуемые входы/выходы;
- сообщения об ошибках формируются централизованно (единый стиль и формат);
- асинхронный код изолирован (например,
api.jsили функции вlogic.js) и не размазан по обработчикам.
1.10. Обзор библиотек и фреймворков
В промышленной разработке формы и валидация часто реализуются с помощью:
- UI-фреймворков (React/Vue/Angular) — для структуры интерфейса;
- библиотек валидации (например, schema-подходы) — для единых правил проверки;
- HTTP-клиентов (Axios и т.д.) — для удобной работы с запросами;
- линтеров/форматтеров (ESLint/Prettier) — для качества кода.
В рамках этой лабораторной работы подключать и устанавливать библиотеки не требуется. Задача — воспроизвести инженерный принцип: разделение ответственности, модульность, централизованная валидация, предсказуемость.
2. Задание
Цель: закрепить регулярные выражения, формы и валидацию, функции обработки данных, асинхронность, fetch/async/await, обработку JSON и контроль ошибок.
2.1. Задания на закрепление теоретического материала
Данный блок выполняется в отдельном файле practice-lr4.js (или в конце script.js, но строго отделить комментариями), чтобы студент мог продемонстрировать понимание теории до доработки предметной области.
Требования к оформлению:
- каждая задача должна завершаться
console.log(...)с выводом результата; - регулярные выражения обязаны применяться явно;
- для асинхронных задач продемонстрировать результат (успех/ошибка) через
console.log(...).
2.1.1. Блок A — регулярные выражения: проверка формата
Задача A1.
Создать функцию isValidDateYMD(s), которая:
- принимает строку
s; - проверяет формат строго
YYYY-MM-DDс помощью RegExp; - возвращает
true/false; - продемонстрировать 3 теста: корректный формат, неверный формат, пустая строка.
Ожидаемый результат:
isValidDateYMD("2026-02-18") === trueisValidDateYMD("18.02.2026") === falseisValidDateYMD("") === false
Задача A2.
Создать функцию isValidTitle(s), которая:
- принимает строку
s; - запрещает ввод “служебных” символов:
<,>,{,},; - использует RegExp и возвращает
true/false; - продемонстрировать 3 теста: обычная строка, строка с
<, строка с;.
Ожидаемый результат:
- корректная фильтрация запрещённых символов.
2.1.2. Блок B — регулярные выражения: извлечение и нормализация
Задача B1.
Создать функцию extractIds(text), которая:
- принимает строку
text; - извлекает все числа из строки с помощью
match(/\d+/g); - возвращает массив чисел (не строк);
- продемонстрировать на строке:
"id=5; id=12; id=30".
Ожидаемый результат:
[5, 12, 30]
Задача B2.
Создать функцию normalizeSpaces(s), которая:
- заменяет любые последовательности пробельных символов на один пробел;
- обрезает пробелы по краям;
- использует
replace(/\s+/g, " ")иtrim(); - продемонстрировать на строке
" A B\t\tC ".
Ожидаемый результат:
"A B C"
2.1.3. Блок C — формы и валидация: модель ошибок
Задача C1.
Создать функцию validateRequired(value, fieldName), которая:
- принимает
value(строка) иfieldName(строка); - возвращает
null, если значение непустое послеtrim(); - возвращает строку ошибки вида:
"Поле <fieldName> обязательно"— если пустое; - продемонстрировать на пустой строке и на строке
" ok ".
Ожидаемый результат:
- для пустого — текст ошибки;
- для непустого —
null.
Задача C2.
Создать функцию validateNumberRange(n, min, max, fieldName), которая:
- принимает число
n, границыmin/max, имя поля; - возвращает
null, еслиn— число и в диапазоне; - возвращает строку ошибки, если
nне число (NaN) или вне диапазона; - продемонстрировать на значениях
10,-1,NaN.
Ожидаемый результат:
- корректные сообщения об ошибках.
2.1.4. Блок D — функции обработки данных: чистые функции
Задача D1.
Создать функцию buildRecordFromForm(raw), которая:
- принимает объект “сырого ввода”
rawвида:{ title: string, value: string, status: string, createdAt: string } - нормализует
titleчерезnormalizeSpaces(...); - преобразует
valueв число; - возвращает новый объект записи без
id(id будет назначаться отдельно); - продемонстрировать в консоли, что
valueстал числом, аtitleнормализован.
Ожидаемый результат:
- корректная нормализация и преобразование типов.
Задача D2.
Создать функцию collectErrors(record), которая:
- принимает объект записи (уже после преобразований);
- использует функции из блоков A/C для проверок;
- возвращает массив строк ошибок (пустой массив, если ошибок нет);
- продемонстрировать минимум 2 кейса: валидный объект и объект с ошибками.
Ожидаемый результат:
- массив ошибок и пустой массив для корректного ввода.
2.1.5. Блок E — асинхронность: Promise и async/await (2 задачи)
Задача E1.
Создать функцию delay(ms), которая:
- возвращает
Promise, выполняющийся черезmsмиллисекунд; - продемонстрировать, что код “ждёт” через
await delay(500)и затем печатает в консоль"done".
Ожидаемый результат:
- в консоли видно, что
"done"появляется после паузы.
Задача E2.
Создать async функцию safeFetchJson(url) (по образцу из теории), которая:
- возвращает объект
{ ok: true, data }или{ ok: false, error, details }; - продемонстрировать вызов на тестовом URL (любой публичный JSON) или на заведомо некорректном URL (чтобы показать обработку ошибки);
- вывести результат в консоль.
Ожидаемый результат:
- есть демонстрация успеха или корректной ошибки без падения программы.
2.1.6. Блок F — обработка JSON и контроль ошибок
Задача F1.
Создать функцию tryParseJson(text), которая:
- принимает строку
text; - возвращает
{ ok: true, data }, еслиJSON.parseуспешен; - возвращает
{ ok: false, error }, если парсинг не удался; - продемонстрировать на корректном JSON (
'{"a":1}') и некорректном ('{a:1}').
Ожидаемый результат:
- корректные результаты без исключений наружу.
Задача F2.
Создать функцию normalizeApiValue(x), которая:
- принимает значение
x(может быть строкой, числом,null); -
возвращает число:
-
если
x— число → вернуть его; - если
x— строка с числом → преобразовать; - иначе → вернуть
0; - продемонстрировать на
10,"20",null,"abc".
Ожидаемый результат:
- предсказуемое поведение и отсутствие
NaNв бизнес-логике.
2.2. Требования к модульности проекта (обязательное)
Проект должен оставаться в архитектуре:
data.js— данные предметной области (массив объектов);logic.js— функции обработки данных, валидации и нормализации;script.js— DOM, события, вызовы функций логики;- (допускается)
api.js— функции сетевого доступа (safeFetchJson, преобразование ответа).
Правило: валидация и регулярные выражения не должны быть размазаны по обработчикам. Обработчик формы вызывает одну функцию валидации, получает результат, принимает решение.
3. Итоговая задача: “Интерактивный список записей 2.0” (ЛР1 → ЛР2 → ЛР3 → ЛР4)
Цель: продолжить развитие интерфейса проекта семестра, добавив формы, валидацию на RegExp, качество кода и асинхронную интеграцию с внешним сервисом.
3.1. Модификация верстки index.html (форма + ошибки + кнопки интеграции)
В существующую верстку проекта добавить:
- Форму добавления записи (минимум 4 поля) и кнопку “Сохранить”.
- Блок вывода ошибок формы
#formErrors(список или текст). -
Кнопку для асинхронной интеграции, например:
-
“Загрузить данные из внешнего сервиса”
- или “Обновить справочник статусов”
- или “Подтянуть доп. данные по записи”.
- (Остаётся) блок управления, контейнер списка
#list, область сообщений#message.
Рекомендуемая минимальная форма:
<form id="recordForm">
<input id="titleInput" name="title" placeholder="Название" />
<input id="valueInput" name="value" placeholder="Value" />
<input id="createdAtInput" name="createdAt" placeholder="YYYY-MM-DD" />
<select id="statusInput" name="status">
<option value="new">new</option>
<option value="done">done</option>
</select>
<button type="submit">Сохранить</button>
</form>
<div id="formErrors"></div>
3.2. Требования к логике и архитектуре
- данные находятся в
data.js(массив объектов); - обработка данных оформлена функциями в
logic.js; - работа с DOM, событиями и вызовами функций выполняется в
script.js; - интерфейс обновляется через
renderList(...); - запрещено дублировать одинаковую обработку данных в нескольких обработчиках;
- регулярные выражения используются для валидации минимум 2 полей;
- асинхронный
fetchоформлен как функция, которая не ломает UI при ошибках.
3.3. Валидация формы
Форма должна проверяться до добавления записи в массив items.
Минимальные правила валидации:
title— обязательное поле, нормализация пробелов обязательна.title— запрет символов<,>,{,},;(через RegExp).value— число и в диапазоне (например>= 0и<= 1_000_000).createdAt— форматYYYY-MM-DD(RegExp) + смысловая проверка (например,Date.parseили проверка, что дата корректна).-
При ошибках:
-
запись не добавляется;
- ошибки выводятся в
#formErrors; - в
#messageможно вывести краткое сообщение “Исправьте ошибки формы”.
3.4. Добавление записи через форму
При успешной валидации:
- Формируется новый объект записи (нормализация + преобразование типов).
- Назначается новый
id(например,maxId + 1). - Запись добавляется в
items. - Обновляется интерфейс
renderList(items). - Форма очищается (
form.reset()или ручная очистка полей). - Сообщение об успехе выводится в
#message.
3.5. Асинхронная интеграция с внешним сервисом
Необходимо реализовать один из вариантов интеграции (любой один, но полностью):
Вариант A (рекомендуемый): загрузка внешних записей и добавление в список. Сценарий:
- Кнопка “Загрузить данные” запускает
asyncфункцию. - Выполняется
fetch(...), получаем JSON. - Данные преобразуются в формат ваших записей (минимум
title/value/status/createdAt). - Добавляются в
items(например, 3–5 записей). - UI обновляется
renderList(items). -
При ошибке:
-
UI не падает;
- в
#messageвыводится ошибка (человеко-понятная); - подробности можно выводить в консоль.
Вариант B: загрузка справочника статусов (массив строк) и обновление <select> в форме.
Сценарий:
fetchполучает массив статусов.selectпересобирается через DOM.- Выводится сообщение об успехе/ошибке.
Вариант C: обогащение данных записи (например, подгрузка “доп. инфо” по id). Сценарий:
- Пользователь нажимает “Обновить” на карточке.
- По
idделаетсяfetch, возвращается JSON. - Запись обновляется в массиве, затем
renderList(...).
3.6. Обязательные сценарии итоговой задачи
Студент обязан продемонстрировать:
- Все сценарии ЛР3 (показ всех, фильтр
new, сортировка поvalue↓, статистика, кнопка удаления сdataset). - Наличие формы добавления записи.
- Валидацию формы с использованием регулярных выражений (минимум 2 правила на RegExp).
- Добавление записи в массив
itemsтолько при успешной валидации. - Асинхронный сценарий
fetch/async/awaitс обработкой JSON и контролем ошибок (без падения интерфейса).
3.7. Требования к сдаче
В одном репозитории должны быть:
- обновлённый
index.html(форма,#formErrors, кнопка интеграции,#list,#message); data.js(массив объектов);logic.js(валидация, нормализация, функции обработки данных);script.js(DOM + события + renderList + управление формой);- (при необходимости)
api.js(сетевой слой); - уточнение в
README.md(что добавлено в ЛР4: форма, валидация, fetch); passport.mdостаётся и используется дальше.
3.8. Запрет
❗ Запрещается использование систем искусственного интеллекта для выполнения лабораторной работы.
Работы, выполненные с использованием ИИ, полностью или частично скопированные, а также не сданные, оцениваются в 0 баллов без возможности доработки.
4. Контрольные вопросы
- Что такое регулярные выражения и в каких задачах они применяются в web-разработке?
- Чем отличается
re.test(str)отstr.match(re)? - Зачем нужны якоря
^и$при валидации формата? - Почему проверка RegExp не всегда гарантирует корректность значения (пример: дата)?
- Что такое нормализация ввода и зачем она нужна (пример с пробелами)?
- Как работает событие
submitформы и зачем нуженpreventDefault()? - В чём разница между синхронным и асинхронным кодом в JavaScript?
- Что возвращает
fetchи почему безawaitнельзя сразу получить данные? - Как правильно обработать ошибки сети и HTTP-статусы при запросе?
- Почему валидацию и сетевые запросы нужно выносить в функции и модули, а не писать внутри обработчиков?
5. Чек-лист для самопроверки
| Баллы | Критерии оценки |
|---|---|
| 20 | Выполнены задания на закрепление теории (блок 2.1: по 2 задачи на каждый блок A–F, результаты выведены в консоль, ошибок нет); в проекте реализованы форма и блок ошибок (#formErrors), введена валидация с использованием регулярных выражений (минимум 2 правила RegExp) и смысловых проверок; добавление записи происходит только при успешной валидации; реализован асинхронный сценарий fetch через async/await с обработкой JSON и контролем ошибок (ошибки не ломают UI, сообщение выводится в #message); сохранена архитектура (data.js, logic.js, script.js, при необходимости api.js), нет дублирования логики в обработчиках; сохранены и работают все сценарии ЛР3 (показ всех, фильтр new, сортировка, статистика, удаление через dataset); изменения зафиксированы в GitHub (коммиты и актуальные файлы). |
| 16–19 | Теоретический блок 2.1 выполнен почти полностью (допущены 1–2 недочёта: не выведен результат одной задачи, есть незначительная ошибка), и/или валидация реализована частично (например, только формат без смысловой проверки), и/или асинхронность работает, но обработка ошибок неполная (например, не проверяется resp.ok), при этом проект не падает, архитектура в целом соблюдена и ключевые сценарии ЛР3 сохранены. |
| 12–15 | Теоретический блок 2.1 выполнен частично (не все блоки A–F), и/или форма есть, но валидация слабая (ошибки не показываются или правила RegExp формальны), и/или асинхронный сценарий есть, но результаты не интегрируются в проект (только вывод в консоль), и/или нарушена модульность (валидация/RegExp/сетевой код в обработчиках), при этом часть сценариев ЛР3 может быть реализована не полностью. |
| 8–11 | Форма присутствует, но добавление записи нестабильно (нет устойчивой валидации, возможны NaN/пустые поля), регулярные выражения используются формально или отсутствуют, fetch/async не демонстрируется или приводит к ошибкам, сообщения пользователю неструктурированы, модульность нарушена, интерфейс может работать фрагментарно. |
| 1–7 | Формальный шаблон без рабочей логики: отсутствует теоретический блок 2.1, нет корректной валидации, нет RegExp, нет асинхронной интеграции, интерфейс ломается при ошибках, модульность отсутствует, базовые сценарии ЛР3 не сохранены. |
| 0 | Работа не сдана / неработоспособна / выполнена с использованием ИИ. |