عبارات با قاعده در PHP / بخش اول

عبارات با قاعده، به نظر خیلی ها ترسناکه. به نظر خودم هم بود. تا اینکه یه کتاب خوندم دربارش و تازه پی بردم به قدرتش. (این کتاب مورد نظره : Mastering Regular Expressions نوشته Jeffrey E. F. Friedl ، منتها من نسخه ای رو خوندم که غیر قانونی دانلود شده بود و به اشتراک گذاشتن این نسخه خیلی خیلی بدتره از خوندنش!! خودتون میتونید تو وب پیداش کنید)
حالا این سری من میخوام چند تا از مهمترینهاشون رو توضیح بدم، تا هرجا که اعصابم اجازه بده!!(یا به عبارتی من قصد ندارم اینجا راهنمای کامل بنویسم. فقط یه راهنمایی مختصر!!)

توی PHP ما دو جور عبارت با قاعده داریم. یکی عبارات با قاعده POSIX Extended ، ودومی عبارات با قاعده Perl Compatible.
برای اولی تمام توابع با eregi و ereg شروع میشه. مثلا eregi_replace ولی برای دومی (Perl) این توابع با preg شروع میشن، مثل preg_replace . البته این دو تا یه سری تفاوتها دارن، من همیشه از دومی استفاده میکنم چون سریعتر و کاملتر هستن. یه تفاوت مهم اینه که توی دومی، عبارات با قاعده داخل دو تا / (علامت اسلش) قرار میگیرن.

خوب یه مثال :
   
^[a-zA-Z0-9._-]+@[a-zA-Z0-9-]+\.[a-zA-Z.]{2,5}$

خوب این معمولا الگویی هستش که برای شناسایی آدرس ایمیل استفاده میشه. خوب این یعنی چی؟ این مثال هم طریقه استفاده ازش با کمک php :
   
<?php
   $pattern = "/^[a-zA-Z0-9._-]+@[a-zA-Z0-9-]+\.[a-zA-Z.]{2,5}$/";
   $email = "mine@example.com";
    
   if (preg_match($pattern,$email))
      echo "Match";
   else
      echo "Not match";

خوب قضیه سادست. من از توابع مربوط به PCRE (یا همون Perl Compatible) استفاده کردم، پس ببینید که دو طرفش دو تا اسلش گذاشتم. البته همین دو تا اسلش رو بردارید و از تابع eregi استفاده کنید به جای این تابع preg_match باز هم جواب میده. خوب حالا توضیح مختصری درباره این عبارات داخل یه عبارت با قاعده.
خوب اول از همه، وقتی شما دنبال یه کلمه خاص میگردید، مثلا کلمه hello داخل یه جمله، الگوی با قاعده شما میشه همون کلمه. اینو میشه با خیلی توابع رشته ای هم انجام داد. مثلا :
   
//We search for this (just hello not /hello/ two / is required for the function!):
$pattern="/hello/";
//In this string :
$subject="hello world!";
if (preg_match($pattern,$subject))
   echo "Match"; //<==Answer
else
   echo "Not match";

دقت کنید من همیشه دو طرف الگو (که همیشه اسمشو میذارم pattern ) یه جفت اسلش گذاشتم، این به خاطر روش پرل هست نه جزیی از رشته.

کاراکتر بک اسلش “\”
قبل از هر کاراکتر دیگه ای، این کاراکتر باید معرفی بشه. این کاراکتر برای اینه که کلیه کاراکترهای دیگه رو بی معنی کنه. مثلا کاراکتر ^ رو پایینتر معرفی میکنم. اگه توی الگو بیاد، معنی خاصی داره. حالا اگه ما بخوایم خود کاراکتر رو بنویسیم نه معنی خاصش رو چی؟ کافیه قبل از کاراکتر یه بک اسلش بذاریم.
کاراکتر “^”
این کاراکتر، یعنی آغاز خط. مثلا شما میخواید چک کنید و ببینید که یه جمله با hello شروع شده یا نه؟مثلا :
   
//We search for this :
$pattern="/^hello/";
//In this string :
$subject="hello world!";
if (preg_match($pattern,$subject))
   echo "Match"; //<==Answer
else
   echo "Not match";

به عبارتی، همون الگوی قبلی هستش، فقط و فقط اینکه ما همون الگو رو میخوایم منتها باید در ابتدای جمله باشه و نه هر جایی از جمله. مثلا اگه subject باشه world hello دیگه این الگو باهاش مچ نمیشه.
کاراکتر “$”
این دقیقا برعکس قبلیه هستش. یعنی پایان خط. به طور مثال :
   
//We search for this :
$pattern="/hello$/";
//In this string :
$subject="hello world!";
if (preg_match($pattern,$subject))
   echo "Match";
else
   echo "Not match"; //<==Answer

یعنی این جایی مچ میشه که اول، کلمه hello بیاد و بعد بلافاصله جمله تموم بشه.مثلا اگه subject باشه world hello مثال بالایی درست میشه.
حالا اگه ما جمله ای رو بخوایم که فقط و فقط یه کلمه hello توش باشه الگوش میشه این :
   
/^hello$/

کاراکتر نقطه “.”
این کاراکتر به معنی همه کاراکترها میشه.البته به جز کاراکتر خط جدید. مثلا میخواید الگویی رو پیدا کنید که مثلا با he شروع شده باشه و با lo تموم. میشه اینطوری الگو رو نوشت :
   
/he.lo/

خوب این الگو، کلماتی رو پیدا میکنه مثل hello – he78686hhjulo یا حتی he lo ولی نه helo .
کاراکتر پایپ “|”
این کاراکتر، یه جورایی به معنی یا میشه. مثلا اگه شما دنبال hello میگردید یا hallo میتونید بنویسید :
   
/hello|hallo/

پرانتز باز و پرانتز بسته “()”
مثال بالایی رو ببینید. همون hello و hallo ما میتونیم الگو رو یه کم تغییر بدیم. ما کلماتی رو میخوایم که با h شروع شدن، حرف دومشون e هست یا a و بعد در انتها llo . خوب ما میتونیم از زیر الگو استفاده کنیم. یعنی الگویی که داخل الگوی دیگه قرار میگیره. دو طرف این زیر الگو پرانتز قرار میگیره :
   
/h(e|a)llo

اینطور میتونید چند تا الگو رو با هم ترکیب کنید. زیر الگوها تو تابع preg_match_all خیلی مهمتر میشن :)
کاراکتر ستاره “*”
گاهی من مثلا مینویسم hellllllo (خیلی خوشحال که باشم از دیدن کسی ممکنه همچین چیزی هم بنویسم!) و میخوام بگردم دنبال کلیه hello ها، منتها اینکه نمیدونم چند تا l ممکنه باشه. یکی ، دو تا ، ?? تا یا اصلا هیچی (لابد هیچی l یعنی اینکه اصلا از دیدنت خوشحال نشدم !!) میتونم از * استفاده کنم. برای این که گفتم :
   
/hel*o/

نکته مهم اینه که میشه از این * بعد از پرانتز بسته قرار بگیره. اینجوری از اون زیر الگو هر چند تا که داشته باشیم پشت سر هم قبوله به طور مثال :
   
/h(e|a)*llo

میشه یه h بعد از اون هر چند تا a یا e که باشه مهم نیست (حتی اگه هیچی باشه) و بعد از اونها llo . خوب برای مثال : heeaeaeallo درسته. hllo هم درسته.
کاراکتر بعلاوه “+”
خوب این دقیقا شبیه * عمل میکنه، منتها دیگه هیچی رو قبول نمیکنه. یعنی تکرار بیشتر از یکی. برای مثال :
   
/h(e|a)+llo

در این حالت hllo قبول نیست ولی در حالتی که از ستاره استفاده کرده بودم، قبول بود.
کاراکتر علامت سوال “?”
این کاراکتر یعنی از کاراکتر یا زیر الگوی قبلی صفر و یا یک بار تکرار شده باشه. مثلا
   
/h(e|a)?llo

یعنی اول یه h بعد دقیقا هیچی یا فقط یکی a یا e و بعدش llo . مثلا hello یا hllo یا hallo ولی نه heello یا heallo .