تابع preg_match() در PHP
تابع preg_match() یکی از توابع پایهای PHP برای بررسی و استخراج متن با استفاده از عبارات منظم (Regular Expressions) بر پایه PCRE است. این تابع برای چک کردن اینکه آیا یک الگو در یک رشته وجود دارد یا خیر و همچنین گرفتن گروههای متناظر بسیار کاربردی است.
فرم کلی و مقادیر بازگشتی
امضای ساده تابع:
int preg_match ( string $pattern , string $subject , array &$matches = null , int $flags = 0 , int $offset = 0 )توضیح بازگشتی:
| مقدار | معنی |
|---|---|
| 1 | مطابقت پیدا شد |
| 0 | هیچ مطابقتی وجود نداشت |
| false | خطا (مثلاً الگوی نامعتبر) |
نکات کلیدی
- الگو باید بین جداکنندهها (delimiters) قرار گیرد، معمولاً /pattern/.
- برای کار با UTF-8 از مدیفایر u استفاده کنید.
- برای فعال شدن حالت چندخطی از m و برای اینکه نقطه شامل خط جدید هم شود از s استفاده کنید.
- برای جلوگیری از اشتباه در کاراکترهای خاص، از
preg_quote()استفاده کنید.
مثالهای عملی
1) بررسی فرمت ساده شماره موبایل (ایرانی)
$phone = '09121234567';
if (preg_match('/^09d{9}$/', $phone)) {
echo 'Valid mobile';
} else {
echo 'Invalid mobile';
}در این مثال الگو بررسی میکند که رشته با 09 شروع شده و دقیقاً 9 رقم بعد از آن وجود دارد. اگر مطابقت وجود داشته باشد مقدار 1 بازمیگردد.
2) استخراج گروهها (Capturing Groups)
$date = '2025-11-07';
if (preg_match('/^(d{4})-(d{2})-(d{2})$/', $date, $matches)) {
// $matches[0] => '2025-11-07'
// $matches[1] => '2025'
// $matches[2] => '11'
// $matches[3] => '07'
print_r($matches);
}در این کد با استفاده از پرانتزها سه گروه گرفته شده و در آرایه $matches قرار میگیرند. اندیس صفر همیشه متن کامل مطابقت است.
3) استفاده از Named Groups و گرفتن آفستها
$text = 'Price: $123.45';
if (preg_match('/Price:s+$(?Pd+.d{2})/', $text, $m, PREG_OFFSET_CAPTURE)) {
// $m['amount'][0] => '123.45'
// $m['amount'][1] => offset position
print_r($m);
}در اینجا از named group با نام amount استفاده شده و با فلگ PREG_OFFSET_CAPTURE علاوه بر متن مطابقت، جایگاه (offset) در رشته نیز بازگردانده میشود.
4) کار با متنهای فارسی و یونیکد
$name = 'علی رضایی';
if (preg_match('/^[p{L}s]+$/u', $name)) {
echo 'Valid Persian name';
} else {
echo 'Invalid name';
}مد u باعث میشود الگو بر پایه UTF-8 پردازش شود. از کلاس کاراکتر p{L} برای تطابق هر حرف (از هر زبان) استفاده شده است و فاصلهها مجاز هستند.
پیدا کردن چندین مورد: تفاوت با preg_match_all()
اگر به دنبال پیدا کردن همهٔ تطابقها هستید از preg_match_all() استفاده کنید. preg_match() فقط اولین تطابق را بررسی و (در صورت درخواست) ذخیره میکند.
$text = 'apple banana apple';
preg_match_all('/apple/', $text, $all);
print_r($all);در این مثال preg_match_all هر دو مطابقت ‘apple’ را بازمیگرداند، در حالی که preg_match فقط اولین را گزارش میدهد.
اشتباهات رایج و راهکارها
- فراموش کردن جداکننده (/): الگو بدون جداکننده معتبر خطا میدهد و تابع مقدار
falseبازمیگرداند. - عدم استفاده از
uبرای UTF-8: باعث میشود حروف غیرلاتین درست تشخیص داده نشوند. - استفاده از نقطه بدون
s: نقطه به صورت پیشفرض خط جدید را شامل نمیشود. - برای دادههای کاربر که ممکن است شامل کاراکترهای ویژه regex باشند از
preg_quote()قبل قرار دادن در الگو استفاده کنید.
مثال preg_quote()
$keyword = 'C++';
$pattern = '/' . preg_quote($keyword, '/') . '/';
if (preg_match($pattern, 'I love C++')) {
echo 'Found';
}این مثال از preg_quote برای فرار دادن (+) استفاده میکند تا به جای معنی متادیتا در regex، به صورت متن ساده جستجو شود.
عملکرد و بهینهسازی
- از الگوهای سادهتر و مشخصتر استفاده کنید؛ الگوهای بسیار عمومی و سنگین میتوانند هزینه محاسباتی بالایی داشته باشند.
- در صورت امکان از توابع سادهتر PHP (مانند
strpos،substr) استفاده کنید چون سریعتر هستند. - از greedy vs lazy آگاه باشید:
.*طمعکار است و میتواند نتایج غیرمنتظره یا کندی ایجاد کند؛ از.*?برای کمینهگرا استفاده کنید.
مثال کامل: بررسی ایمیل با هشدار
$email = 'user@example.com';
$pattern = '/^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+.[A-Za-z]{2,}$/';
if (preg_match($pattern, $email)) {
echo 'Seems valid';
} else {
echo 'Invalid';
}این الگو یک بررسی پایهای ایمیل انجام میدهد اما توجه داشته باشید که برای اعتبارسنجی دقیق ایمیل از filter_var($email, FILTER_VALIDATE_EMAIL) استفاده کنید؛ regex ممکن است همهٔ موارد استاندارد RFC را پوشش ندهد.
خلاصه و نکات پایانی
- preg_match() ابزار قدرتمندی برای تشخیص و استخراج الگوهاست اما باید با احتیاط و دانش ساخته شود.
- همیشه الگوها را تست کنید و برای دادههای کاربر از
preg_quote()بهره ببرید. - برای متنهای یونیکد مد
uرا فراموش نکنید و در صورت نیاز به همهٔ تطابقها ازpreg_match_all()استفاده کنید.
مطالعه مستندات رسمی PHP و تست الگوها با ابزارهای آنلاین (Regex101 با حالت PHP/PCRE) میتواند به درک بهتر و عیبیابی سریع کمک کند.
آیا این مطلب برای شما مفید بود ؟



