Signature
preg_split(string $pattern, string $subject, int $limit = -1, int $flags = 0): array|falsePurpose
preg_split() cuts a string into pieces wherever a regular expression matches. The matched text is the delimiter and is normally thrown away. Use it when the separator is not one fixed string: "any run of commas and spaces", "a digit boundary", or "an operator I also want to keep". If the separator is a fixed string, explode() is simpler and faster. For fixed-size chunks, str_split() is the better tool.
Signature
Parameters and defaults
$pattern: a full PCRE pattern including delimiters and optional modifiers, for example'/\s+/'.$subject: the string to split.$limit: the maximum number of pieces. With a positive limit, the remainder of the string is left unsplit in the last piece.-1and0both mean no limit. The default is-1.$flags: a bitmask combined with|. The default0sets no flags.
The three flags are:
PREG_SPLIT_NO_EMPTYdrops empty pieces.PREG_SPLIT_DELIM_CAPTUREalso returns text captured by parenthesized groups in the delimiter pattern.PREG_SPLIT_OFFSET_CAPTUREturns every element into a two-item array: the piece and its byte offset in the subject.
Return value and failure
The function returns an array of strings, or an array of [string, offset] pairs when the offset flag is used. It returns false on failure. An invalid pattern emits an E_WARNING and gives false. Runtime problems can also give false; preg_last_error() reports the code. If the pattern never matches, you get an array with one element: the original subject.
Example 1: splitting on a flexible separator
A single pattern can treat commas, spaces and combinations of them as one separator. The + makes consecutive separator characters collapse into one delimiter.
$parts = preg_split('/[\s,]+/', 'red, green blue,yellow');
echo json_encode($parts, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";["red","green","blue","yellow"]
Example 2: keeping delimiters and limiting pieces
When you tokenize an expression, the operators matter as much as the operands. A capturing group together with PREG_SPLIT_DELIM_CAPTURE keeps them in the result. The second call shows limit: the last piece holds the unsplit rest.
$flags = JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES;
$expr = '12+3*4-5';
$tokens = preg_split('/([+*-])/', $expr, -1, PREG_SPLIT_DELIM_CAPTURE);
echo json_encode($tokens, $flags), "\n";
$limited = preg_split('/,/', 'a,b,c,d', 2);
echo json_encode($limited, $flags), "\n";["12","+","3","*","4","-","5"] ["a","b,c,d"]
Example 3: offsets, empty pieces and characters
Leading, trailing and doubled separators produce empty strings unless you ask for them to be removed. An empty pattern matches between every character, so combined with PREG_SPLIT_NO_EMPTY it splits a string into single bytes.
$flags = JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES;
echo json_encode(preg_split('/ /', 'ab cd', -1, PREG_SPLIT_OFFSET_CAPTURE), $flags), "\n";
echo json_encode(preg_split('/,/', ',a,,b,'), $flags), "\n";
echo json_encode(preg_split('/,/', ',a,,b,', -1, PREG_SPLIT_NO_EMPTY), $flags), "\n";
echo json_encode(preg_split('//', 'abc', -1, PREG_SPLIT_NO_EMPTY), $flags), "\n";[["ab",0],["cd",3]] ["","a","","b",""] ["a","b"] ["a","b","c"]
Edge cases
- Empty pieces are normal. A delimiter at the start or end of the subject produces an empty first or last element. Two adjacent delimiters produce an empty element between them. Add
PREG_SPLIT_NO_EMPTYwhen you do not want these. - No match is not failure. You still get an array, containing the whole subject as its only item.
- Offsets are in bytes. With
PREG_SPLIT_OFFSET_CAPTURE, positions count bytes, not characters. This matters for multibyte text. - Unicode needs the
umodifier. Without it,//splits a multibyte character into separate bytes. Withu, an invalid UTF-8 subject can make the call returnfalse. - Limit and empty pieces interact. Combined with
PREG_SPLIT_NO_EMPTY, the limit applies to non-empty pieces, so check the result when you use both.
Common mistakes
- Forgetting delimiters.
preg_split(',', $s)is not a valid pattern. Write'/,/'. - Not escaping literal input. If the separator comes from a variable, pass it through
preg_quote()with the delimiter character, or useexplode()instead. - Ignoring
false. Code such ascount(preg_split(...))orforeachover the result is unsafe when the pattern might be invalid or the subject might not be valid UTF-8. Check forfalsefirst. - Expecting delimiters to be kept automatically. They are discarded unless a capturing group and
PREG_SPLIT_DELIM_CAPTUREare used. A group without the flag does not add anything to the result. - Using regex when plain splitting is enough. A fixed comma separator is clearer and faster with
explode(',', $s). - Treating offset results as strings. With
PREG_SPLIT_OFFSET_CAPTURE, each element is an array, sostrlen($piece)on it will fail.
Related functions
explode()splits by a fixed string.str_split()splits into fixed-length chunks.preg_match()andpreg_match_all()extract matches instead of the text between them.preg_replace()rewrites matched text.preg_quote()escapes literal text for use in a pattern.preg_last_error()reports why a PCRE call failed.
Recap
preg_split() splits at regex matches and returns an array, or false on failure. Use limit to cap the pieces, PREG_SPLIT_NO_EMPTY to drop blanks, PREG_SPLIT_DELIM_CAPTURE to keep captured delimiters, and PREG_SPLIT_OFFSET_CAPTURE to get byte positions. Prefer explode() when the separator is a plain string, and always handle the false case.
Tested examples
$parts = preg_split('/[\s,]+/', 'red, green blue,yellow');
echo json_encode($parts, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
["red","green","blue","yellow"]
$flags = JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES;
$expr = '12+3*4-5';
$tokens = preg_split('/([+*-])/', $expr, -1, PREG_SPLIT_DELIM_CAPTURE);
echo json_encode($tokens, $flags), "\n";
$limited = preg_split('/,/', 'a,b,c,d', 2);
echo json_encode($limited, $flags), "\n";
["12","+","3","*","4","-","5"] ["a","b,c,d"]
$flags = JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES;
echo json_encode(preg_split('/ /', 'ab cd', -1, PREG_SPLIT_OFFSET_CAPTURE), $flags), "\n";
echo json_encode(preg_split('/,/', ',a,,b,'), $flags), "\n";
echo json_encode(preg_split('/,/', ',a,,b,', -1, PREG_SPLIT_NO_EMPTY), $flags), "\n";
echo json_encode(preg_split('//', 'abc', -1, PREG_SPLIT_NO_EMPTY), $flags), "\n";
[["ab",0],["cd",3]] ["","a","","b",""] ["a","b"] ["a","b","c"]