sscanf()
Статья о PHP-функции sscanf(), которая используется для разбора входной строки по заданному формату. Полезна для извлечения типизированных данных.
Функция PHP sscanf() читает строку и извлекает из неё значения согласно описанному вами формату — она является обратной к sprintf(). Там где sprintf() создаёт отформатированную строку из переменных, sscanf() разбирает отформатированную строку обратно на переменные. Она особенно полезна, когда текст имеет предсказуемую структуру (даты, координаты, строки журнала, коды идентификаторов) и вам нужны чистые типизированные части без написания регулярного выражения.
В этой главе рассматриваются синтаксис, два способа получения результатов, форматные спецификаторы, которые вы реально будете использовать, и типичные ловушки.
Синтаксис
sscanf(string $string, string $format, mixed &...$vars): array|int|null$string— входной текст для разбора.$format— шаблон, описывающий, что читать, с использованием спецификаторов%(то же семейство, что и уprintf).&...$vars— необязательные переменные, передаваемые по ссылке, которые получают разобранные значения.
Поведение sscanf() зависит от того, передаёте ли вы дополнительные переменные:
| Способ вызова | Возвращаемое значение |
|---|---|
Только $string и $format | Массив разобранных значений |
С переменными-ссылками после $format | int: количество успешно присвоенных значений |
Получение значений в виде массива
Если не передавать аргументы-ссылки, sscanf() возвращает всё в виде массива. Это наиболее чистый стиль в современном PHP, позволяющий избежать передачи переменных по ссылке.
%s читает следующее слово без пробелов (John), а %d читает целое число (25, сохранённое как настоящий int, а не строка "25"). Вывод:
John
25Присваивание непосредственно в переменные
При передаче переменных после формата значения присваиваются в них напрямую. В этом режиме возвращаемое значение — количество совпавших полей, что удобно для валидации входных данных.
<?php
$input = 'John 25';
$matched = sscanf($input, '%s %d', $name, $age);
echo $matched . "\n"; // 2 (both fields were read)
echo $name . "\n"; // John
echo $age; // 25
?>Примечание: в PHP 8 префикс
&при вызове (например,sscanf($s, $f, &$name)) был удалён. Просто передавайте переменную без префикса —sscanf()сам объявляет эти параметры как передаваемые по ссылке.
Распространённые форматные спецификаторы
| Спецификатор | Читает |
|---|---|
%s | Строку до следующего пробела |
%d | Знаковое десятичное целое число |
%f | Число с плавающей точкой |
%x | Шестнадцатеричное целое число |
%c | Одиночный символ |
%% | Литеральный знак % |
Литеральные символы в формате (пробелы, слэши, двоеточия) должны присутствовать и во входных данных. Это делает sscanf() отличным инструментом для данных фиксированной структуры, таких как даты:
<?php
$date = '2026-06-21';
[$year, $month, $day] = sscanf($date, '%d-%d-%d');
printf("Year=%d Month=%d Day=%d", $year, $month, $day);
// Year=2026 Month=6 Day=21
?>Когда использовать sscanf() вместо альтернатив
- Используйте
sscanf(), когда формат фиксированный и простой и вам нужны типизированные результаты в одну строку. - Используйте
explode(), когда нужно лишь разбить строку по разделителю и оставить всё как строки. - Используйте
preg_match(), когда структура нерегулярна или требует правил валидации, выходящих за рамки простых типов полей. - Для обратной операции — сборки отформатированной строки — используйте
sprintf()илиprintf().
Чтобы читать форматированные данные непосредственно из файла, а не из строки, см. fscanf(), которая работает аналогично, строка за строкой.
Ловушки
%sостанавливается на пробеле. Он не захватит значение из нескольких слов. Чтобы прочитать остаток строки, используйте набор символов сканирования, например%[^\n].- Несовпадающее поле прерывает дальнейший разбор. Если ожидается
%d, но во входных данных буквы, разбор останавливается; возвращаемое значение-счётчик позволяет это обнаружить. - Несовпавшие оставшиеся переменные становятся
null. Всегда проверяйте возвращённый счётчик перед использованием последующих переменных.