В современных информационных системах‚ связанных с реестром водительских прав‚ часто требуется выполнять поиск по различным полям (фамилия‚ серия‑номер‚ категория‚ ограничения и т.д.). Для упрощения поиска в запросах используют специальные символы‑шаблоны. Наиболее популярные из них – это знак вопроса (?) и звёздочка (*). В статье подробно рассматривается их смысл‚ способы применения‚ нюансы экранирования и типичные ошибки.
Общие принципы работы со спецсимволами
Большинство реестров реализованы как базы данных (SQL‚ NoSQL) или как веб‑сервисы с поддержкой URI-запросов. В обоих случаях символы ? и * выступают в роли подстановочных знаков (wildcards) и позволяют искать записи‚ частично совпадающие с заданным шаблоном.
Где они применяются?
- В SQL‑операторах
LIKE(в некоторых диалектах вместо%и_можно задать собственные шаблоны‚ напримерSIMILAR TO). - В поисковых API реестра (REST‑сервисы‚ SOAP‑вызовы) – часто в параметрах
searchилиfilter. - В интерфейсе пользователя (веб‑формы‚ мобильные приложения) – пользователь вводит запрос с
?и*‚ а система преобразует их в корректный запрос к базе.
Что означают символы?
?– одиночный подстановочный символ. Заменяется ровно одним произвольным символом (буквой‚ цифрой‚ пробелом).- – многократный подстановочный символ. Заменяется любой последовательностью символов‚ включая пустую строку.
Пример: запрос ИВАН П?ТРОВ найдёт записи ИВАНОВ ПЕТРОВ‚ ИВАНСКИЙ ПАТРОВ‚ ИВАН ПИТОВ и т.д.
Техническая реализация в разных средах
SQL‑подстановки
Стандартный SQL использует % (многосимвольный) и _ (одиночный). Чтобы поддержать ? и ‚ обычно применяется предобработка строки:
-- Пример на PostgreSQL
SELECT
FROM driver_registry
WHERE full_name ILIKE REPLACE(REPLACE(:search‚ ''‚ '%')‚ '?'‚ '_');
В этом примере пользовательский ввод ИВАН П?ТРОВ преобразуется в ИВАН% П_ТРОВ‚ после чего ILIKE ищет без учёта регистра.
NoSQL (MongoDB)
MongoDB поддерживает регулярные выражения. Преобразование выглядит так:
let pattern = userInput
.replace(/[.+?^${}|[]\]/g‚ '\$&') // экранирование специальных regex‑символов
;replace(//g‚ '.*')
.replace(/?/g‚ '.');
db.drivers.find({ fullName: { $regex: '^' + pattern + '$'‚ $options: 'i' } });
REST‑API реестра
В большинстве публичных API параметры передаются в URL. Специальные символы необходимо URL‑кодировать:
?→%3F*→%2A
Пример GET‑запроса:
GET https://api.gibdd.example.com/v1/drivers?filter=fullName:ИВАН%2A%20П%3FТРОВ
Пример на Python (requests)
import requests
import urllib.parse
def search_driver(query):
encoded = urllib.parse.quote(query‚ safe='')
url = f"https://api.gibdd.example.com/v1/drivers?filter=fullName:{encoded}"
resp = requests.get(url)
resp.raise_for_status
return resp.json
result = search_driver("ИВАН* П?ТРОВ")
print(result)
Правила экранирования и защита от инъекций
Неправильная обработка ? и может привести к двум типам уязвимостей:
- SQL‑инъекция – если пользовательский ввод вставляется в запрос без параметризации.
- Неожиданный перебор – слишком «широкие» шаблоны ( без ограничений) могут вызвать нагрузку на сервер.
Параметризованные запросы
Всегда используйте подготовленные выражения (prepared statements). Пример на Java (JDBC):
String sql = "SELECT * FROM driver_registry WHERE full_name ILIKE REPLACE(REPLACE(?‚ '*'‚ '%')‚ '?'‚ '_')";
PreparedStatement ps = connection.prepareStatement(sql);
ps.setString(1‚ userInput);
ResultSet rs = ps.executeQuery;
Ограничение длины и количества подстановок
Для защиты от «длинных» запросов рекомендуется:
- Ограничить длину строки ввода (например‚ ≤ ).
- Запретить более 3‑х подряд идущих (например‚ → ).
- Отбрасывать запросы‚ где
*или?находятся в начале без последующего текста (это может вернуть почти всю таблицу).
Практические сценарии использования
Поиск по фамилии с неизвестным окончанием
Запрос: ИВАН* – найдёт всех‚ чьи фамилии начинаются на «ИВАН» (Иванов‚ Ивановский‚ Иваненко).
Поиск по серии и номеру‚ где известна только часть номера
Запрос: 78?123456 – найдёт все номера‚ где третий символ может быть любым (например‚ 781123456‚ 782123456).
Комбинированный поиск по категории и ограничениям
Если в реестре есть поле restrictions‚ можно искать водителей с автоматической коробкой (AT) и неизвестным дополнительным ограничением:
SELECT * FROM driver_registry
WHERE restrictions ILIKE REPLACE(REPLACE('AT'‚ ''‚ '%')‚ '?'‚ '_');
Часто задаваемые вопросы (FAQ)
Можно ли использовать ? и одновременно?
Да. ? заменяет ровно один символ‚ а – любую последовательность. Комбинация позволяет задавать гибкие шаблоны‚ например А?В найдёт строки‚ начинающиеся с «А»‚ заканчивающиеся «В»‚ и имеющие хотя бы один символ между ними.
Что делать‚ если пользователь вводит символ как обычный символ‚ а не как подстановку?
Необходимо предоставить возможность «экранирования». Чаще всего используют обратный слеш () или двойные кавычки. При обработке строки заменяйте на литеральный до применения шаблона.
Какой символ использовать в API‚ если сервер поддерживает только % и _?
В таком случае клиентская часть должна преобразовать → % и ? → _ перед отправкой запроса.
Лучшие практики и рекомендации
- Всегда валидируйте ввод. Проверяйте‚ что строка не содержит недопустимых символов (например‚
';--). - Экранируйте специальные символы. При построении регулярных выражений или SQL‑шаблонов заменяйте ‚
.‚+и др. на безопасные эквиваленты. - Используйте параметризацию. Это самый надёжный способ избежать SQL‑инъекций.
- Ограничьте «ширину» запросов. Не допускайте запросов вида без дополнительных условий.
- Логируйте запросы. Записывайте оригинальный ввод и полученный SQL/REST‑запрос для последующего аудита.
Символы ? и – мощный инструмент для гибкого поиска в реестре водительских прав. Правильная их обработка требует:
- Понимания семантики (один символ vs. произвольная последовательность).
- Корректного преобразования в язык запросов (SQL‚ NoSQL‚ REST).
- Экранирования и параметризации для защиты от инъекций.
- Ограничения «широких» запросов во избежание излишней нагрузки.
Следуя рекомендациям‚ изложенным в этой статье‚ разработчики смогут реализовать надёжный и удобный поиск по реестру водительских прав‚ а пользователи – быстро находить нужные сведения‚ используя привычные подстановочные символы.
Дата актуализации статьи: 26 августа 2026 г.