Signature
sscanf(string $string, string $format, mixed &...$vars): array|int|nullPurpose
sscanf() is the input counterpart of printf(). Instead of building a string from values, you give it an existing string and a format, and it extracts the values that the format describes. It suits short, regular text such as codes (SN/2350001), dates (2024-03-15) or simple records where a full regular expression feels heavy.
The format is based on the one used by sprintf(), with a few differences that matter when reading input. Conversions are typed: %d produces an integer, %s a string, and so on.
Signature
Parameters
$string: the input text to parse.$format: the pattern to match. Literal characters must match exactly. Any whitespace in the format matches any run of whitespace in the input, so a tab in the format can match a single space....$vars: optional variables passed by reference. Each one receives the value of one conversion, in order. There is no default; if you leave them out, you get an array instead.
Some format details specific to sscanf():
%dreads a decimal number, and%ireads an integer with base detection.%sstops at the first whitespace character, so it reads one word.%nyields the number of characters processed so far.*in place of an argument number (as in%*d) matches the value but discards it.F,g,Gandbare not supported, and the function is not locale-aware.
Return value and failure cases
The return type depends on how you call it:
- With only two arguments, it returns an array of the parsed values. A conversion that could not be filled leaves
nullin its slot. - With extra variables, it returns the number of values assigned.
- If the format expects more substrings than the input contains,
nullcan be returned. With variables, reaching the end of the input before anything has been parsed returns-1.
Parsing stops at the first mismatch. Everything before it is kept, and the rest stays unassigned. The function does not throw for ordinary non-matching text, so check the result yourself.
Example 1: Reading an array of values
When you pass no variables, you receive a list. Here the literal labels in the format must match, and the whitespace between tokens is flexible.
$result = sscanf("age: 25 name: Bob", "age: %d name: %s");
echo json_encode($result, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";[25,"Bob"]
The integer comes back as a real int and the name as a string.
Example 2: Assigning into variables
Passing variables by reference makes the function return a count instead of an array. This is handy for confirming that every field was parsed.
$count = sscanf("2024-03-15", "%d-%d-%d", $year, $month, $day);
echo json_encode([$count, $year, $month, $day]), "\n";[3,2024,3,15]
Note that 03 becomes the integer 3, because %d converts to a number and drops the leading zero.
Example 3: Skipping fields and partial matches
Use %*d to match a number without keeping it. When the input stops matching, the unfilled slots are null.
$skipped = sscanf("10 20 30", "%d %*d %d");
$partial = sscanf("12 apples", "%d %d");
echo json_encode([$skipped, $partial]), "\n";[[10,30],[12,null]]
The first call returns only the first and third numbers. The second call parses 12, fails on apples, and leaves the second slot as null.
Edge cases
- Whitespace is flexible. One space in the format matches several spaces or a tab in the input, but it never requires a specific kind.
%sreads one word. To capture text with spaces, use a character set such as%[^,]to read up to a delimiter, or split the string yourself.- Types follow the conversion.
%dgives integers and%sgives strings. Validate ranges afterward, since the function only checks the shape of the text. - Partial results are normal. A failure in the middle does not discard earlier values, so a
nullentry is the signal that parsing stopped. - Base detection.
%iaccepts prefixes that%ddoes not, so use it only when you want that behavior.
Common mistakes
- Expecting
%sto include spaces."Lewis Carroll"with%syields onlyLewis. Use two%sconversions or a character set. - Not checking for
null. Always test the array fornullentries, or compare the returned count with the number of conversions you expected. - Mixing up the two return styles. With variables you get a count, not the values. Reading the return value as an array in that mode is a bug.
- Mismatched variable count. The number of variables should match the number of non-suppressed conversions. A mismatch is a usage error.
- Treating it as validation.
sscanf("12abc", "%d")succeeds with12. If the whole string must be numeric, use a stricter check. - Assuming locale handling. Decimal separators are not locale-aware, so do not rely on locale settings to parse formatted numbers.
Related functions
sprintf()andprintf(): build formatted output with the same style of format.fscanf(): the same parsing applied to lines read from a file.vsprintf(),vprintf()andfprintf(): formatted output variants.explode(),preg_match()andstr_getcsv(): alternatives when the text is delimiter-based or irregular.
Recap
sscanf() parses a string against a printf-style format. Without variables it returns an array, with variables it returns the count of assigned values, and unmatched slots are null. Remember that %s stops at whitespace, %*d skips a value, and parsing halts at the first mismatch, so check the result before using it.
Tested examples
$result = sscanf("age: 25 name: Bob", "age: %d name: %s");
echo json_encode($result, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
[25,"Bob"]
$count = sscanf("2024-03-15", "%d-%d-%d", $year, $month, $day);
echo json_encode([$count, $year, $month, $day]), "\n";
[3,2024,3,15]
$skipped = sscanf("10 20 30", "%d %*d %d");
$partial = sscanf("12 apples", "%d %d");
echo json_encode([$skipped, $partial]), "\n";
[[10,30],[12,null]]