ویژگی تصویر

تابع preg_grep() در PHP

  /  PHP   /  تابع preg_grep() در PHP
بنر تبلیغاتی الف
آموزش PHP

تابع preg_grep() یکی از توابع مفید در PHP برای فیلتر کردن آرایه‌ها براساس عبارت‌های منظم (regular expressions) است. این تابع به‌سرعت مقادیر آرایه را بررسی کرده و آن‌هایی را که با الگوی مشخص شده تطابق دارند بازمی‌گرداند. در این مقاله به‌صورت جامع، پارامترها، نمونه‌های کاربردی، ترفندها و نکات بهینه‌سازی مربوط به preg_grep() را بررسی می‌کنیم.

نگاه سریع — سینتکس

array preg_grep ( string $pattern , array $input [, int $flags = 0 ] )

این‌جا $pattern یک الگوی PCRE (با جداکننده‌های معمول مانند /pattern/flags) و $input آرایه‌ای است که باید فیلتر شود. پارامتر اختیاری $flags معمولاً برای وارون‌سازی نتایج استفاده می‌شود.

پارامترها و مقدار بازگشتی

  • $pattern: رشته الگوی PCRE (مثلاً ‘/^abc/i’). باید دارای جداکننده (delimiter) باشد.
  • $input: آرایه‌ای از مقادیر (عموماً آرایه‌ای از رشته‌ها) که قرار است با الگو تطابق داده شوند.
  • $flags: مقادیر ممکن شامل PREG_GREP_INVERT (برای بازگرداندن مقادیری که تطابق ندارند) است.

preg_grep در صورتی که موفق باشد آرایه‌ای (حتی خالی) بازمی‌گرداند و در صورت خطا مقدار FALSE برمی‌گردد. نکته مهم: کلیدهای (keys) آرایه ورودی حفظ می‌شوند؛ برای گرفتن آرایه با ایندکس‌های بازنشانی‌شده باید از array_values استفاده کنید.

مثال‌های ساده

<?php
$items = ['apple', 'banana', 'apricot', 'grape'];
$matches = preg_grep('/^ap/', $items);
print_r($matches);
?>

در این مثال، preg_grep همه عناصری که با ‘ap’ شروع می‌شوند (با ^ anchor) را برمی‌گرداند. خروجی آرایه‌ای شامل ‘apple’ و ‘apricot’ خواهد بود و کلیدهای اصلی حفظ می‌شوند.

مثال با گزینهٔ وارون‌سازی

<?php
$items = ['apple', 'banana', 'apricot', 'grape'];
$not_ap = preg_grep('/^ap/', $items, PREG_GREP_INVERT);
print_r($not_ap);
?>

با استفاده از PREG_GREP_INVERT، آرایه برعکس می‌شود و عناصری که با الگو تطابق ندارند برگردانده می‌شوند (مثلاً ‘banana’ و ‘grape’).

مثال با حساسیت به حروف و reindex

<?php
$emails = ['User@Example.com', 'admin@example.com', 'info@site.org'];
$lower_emails = preg_grep('/@example.com$/i', $emails); // /i => case-insensitive
$indexed = array_values($lower_emails); // بازنشانی کلیدها
print_r($indexed);
?>

در این کد از فلگ i برای نادیده‌گرفتن حساسیت به حروف استفاده شده و سپس با array_values کلیدها به صورت متوالی بازنشانی شده‌اند.

استفادهٔ پیشرفته: آرایهٔ چندبعدی و فیلتر بر اساس کلیدها

<?php
$users = [
  ['name' => 'Ali', 'email' => 'ali@example.com'],
  ['name' => 'Sara', 'email' => 'sara@site.org'],
  ['name' => 'Reza', 'email' => 'reza@example.com'],
];
// preg_grep روی آرایه‌های چندبعدی مستقیم کار نمی‌کند، از array_filter + preg_match استفاده می‌کنیم
$filtered = array_filter($users, function($u){
    return preg_match('/@example.com$/', $u['email']);
});
print_r($filtered);
?>

در مثال بالا برای فیلتر روی فیلدهای درونی از array_filter همراه با preg_match استفاده شده که انعطاف بیشتری نسبت به preg_grep برای ساختارهای پیچیده می‌دهد.

نکات، خطاهای متداول و بهترین رویه‌ها

  • الگو باید دارای delimiter باشد؛ فراموش کردن / در ابتدای و انتهای الگو باعث خطا می‌شود.
  • برای کار با متن‌های یونیکد از فلگ /u استفاده کنید تا کلاس‌های p{} و کاراکترهای چندبایتی درست پردازش شوند.
  • preg_grep کلیدهای آرایه را حفظ می‌کند؛ در صورت نیاز به ایندکس متوالی از array_values استفاده کنید.
  • برای فیلتر روی آرایه‌های پیچیده یا دسترسی به کلیدها از ترکیب array_filter و preg_match استفاده کنید.
  • در الگوهای حساس به کاراکترهای خاص (مثل . یا + یا /) از escaping مناسب (.) استفاده کنید یا از preg_quote برای ساختن الگو از داده‌های کاربر کمک بگیرید.

پشتیبانی یونیکد

<?php
$words = ['سلام', 'hello', 'دنیا', 'world'];
$arabic_or_persian = preg_grep('/p{Arabic}+/u', $words);
print_r($arabic_or_persian);
?>

برای شناسایی کاراکترهای فارسی/عربی از کلاس‌های یونیکد و فلگ u استفاده کنید. بدون u ممکن است نتایج نادرست به‌دست آید.

مقایسه با array_filter + preg_match

ویژگیpreg_grep()array_filter + preg_match
سادگیبسیار ساده برای آرایه‌های مسطحنیاز به callback (انعطاف بیشتر)
فیلتر روی مقادیر تو در تومستقیم خیربله (با دسترسی به کلیدها)
حفظ کلیدهابلهبله

بهینه‌سازی و عملکرد

PCRE الگو را برای هر فراخوانی کامپایل می‌کند؛ اگر از یک الگو در حلقه‌های بزرگ چندین بار استفاده می‌کنید، بهتر است طراحی‌تان را طوری تنظیم کنید که preg_grep یا preg_match کمتر فراخوانی شوند. همچنین الگوها را به‌صورت ساده و با Anchor مناسب بنویسید تا کارایی بهتری داشته باشند.

خلاصه و جمع‌بندی

preg_grep() یک ابزار سریع و مفید برای فیلتر کردن آرایه‌های مسطح بر اساس عبارت‌های منظم است. با رعایت نکات مربوط به delimiter، فلگ‌های مناسب (مانند /i و /u)، و توجه به حفظ کلیدها، می‌توان از آن در بسیاری از سناریوها استفاده کرد. برای ساختارهای پیچیده بهتر است از ترکیب array_filter و preg_match بهره ببرید.

آیا این مطلب برای شما مفید بود ؟

خیر
بله
موضوعات شما در انجمن: