preg_grep()
In PHP, regular expressions are an essential tool for handling and manipulating strings. The preg_grep() function is one of the many functions that PHP provides
Introduction
preg_grep() filters an array, keeping only the elements that match (or, optionally, don't match) a regular expression. It is the array-oriented member of PHP's PCRE family: instead of testing one string like preg_match(), it loops over every element of an array and returns a new array of the elements that pass the test.
This page covers the function's signature and parameters, the difference between matching and inverted matching, how the returned keys behave, common real-world uses, and the gotchas to watch for.
Syntax
preg_grep(string $pattern, array $array, int $flags = 0): array|falseThe function accepts three parameters:
$pattern— a PCRE pattern, written as a string with delimiters (e.g./^g/,~\d+~,#error#i).$array— the input array to filter. Only its values are tested, never its keys.$flags(optional) — pass thePREG_GREP_INVERTconstant to return the elements that do not match. Defaults to0(return matching elements).
It returns a new array containing the matching elements, preserving the original keys. If the pattern is invalid it returns false and emits a warning.
Basic example
preg_grep() walks the array and keeps every value that matches the pattern. Here we keep only the colors that start with the letter g:
Output:
Array
(
[2] => green
)Notice the key: green was at index 2 in the input, and preg_grep() keeps that key in the result. The returned array is therefore not re-indexed — if you need sequential keys, wrap the call in array_values().
Filtering with PREG_GREP_INVERT
Pass PREG_GREP_INVERT as the third argument to flip the logic: you get back the elements that fail the pattern. This is handy for "remove the bad entries" tasks. Here we drop every string that contains a digit:
<?php
$entries = ["apple1", "banana", "cherry7", "date", "fig2"];
$result = preg_grep("/[0-9]/", $entries, PREG_GREP_INVERT);
print_r($result);Output:
Array
(
[1] => banana
[3] => date
)Only banana and date survive because they contain no digits — and again their original keys (1 and 3) are preserved.
Practical use cases
Filtering log lines by level
A common job is pulling just the error lines out of a list of log entries. A case-sensitive anchored pattern keeps it precise:
<?php
$logs = [
"INFO ok",
"ERROR disk full",
"WARN low mem",
"ERROR timeout",
];
$errors = preg_grep("/^ERROR/", $logs);
print_r($errors);Output:
Array
(
[1] => ERROR disk full
[3] => ERROR timeout
)Keeping only fully numeric strings
When validating mixed input, preg_grep() lets you keep only the values that match a strict shape in a single line. The ^\d+$ anchors ensure the whole string is digits:
<?php
$mixed = ["12", "ab", "3x", "99"];
$nums = preg_grep("/^\d+$/", $mixed);
print_r($nums);Output:
Array
(
[0] => 12
[3] => 99
)Gotchas and tips
- Keys are preserved, not reset. As shown above, gaps in the result keys are normal. Use
array_values()if you need0, 1, 2, …. - Only values are tested.
preg_grep()ignores array keys entirely — there is no key-based variant. - Invalid patterns return
false, not an empty array. Always validate the result type if the pattern comes from user input:if ($result === false) { /* bad pattern */ }. - It does not modify the input. Like most PHP array helpers, it returns a new array and leaves
$arrayuntouched. - Non-string values are coerced. Numbers and other scalars are converted to strings before matching, so
preg_grep("/^1/", [10, 20])matches10.
Related functions
preg_match()— test a single string against a pattern.preg_match_all()— find all matches within one string.preg_replace()— search and replace using a pattern.preg_split()— split a string into an array by a pattern.preg_filter()— likepreg_replace()but returns only matched subjects.
Conclusion
preg_grep() is the cleanest way to filter an array against a regular expression in PHP. Use it on its own to keep matching elements, add PREG_GREP_INVERT to remove them, and remember that it preserves the original keys. For single-string matching reach for preg_match(); for replacing reach for preg_replace().