آموزش عبارت های منظم در PHP

درود,

در این جا می خوام آموزش کار با عبارات منظم در PHP رو بهتون یاد بدم .

خب عبارت منظم چیه اصلن ؟ فرض کنیم ما می خوایم یک سری عبارات رو یک مکرر طی یک فراِید خاص تکرار شدن رو پیدا کنیم و یا بخوایم ببینیم عبارتی که مورد نظر ما هست صحیح هست یا نه

برای مثال فرض کنیم می خوایم ببینیم کاربری ایمیل صحیح وارد کرده یا نه ؟ خوب میدونیم ایمیل شامل کاراکتر انگلیسی و – و عدد هست و همه ایمیل ها @ دارن و ...

اینطور با عبارت منظم میشه چک کرد صحت ایمیل رو

یا فرض کنید می خوایم ببینیم یک آی پی درست وارد شده یا نه

خب می دونیم که ایپی 4 شامل 4 قسمت هست که با . از هم جدا شده اند و اعداد بین 0 تا 255 میتونه بین هرکدوم باشه

با عبارات منظم می تونیم صحت این آی پی رو بررسی کنیم.

و خیلی کارای دیگه که باهاش توی آموزش‌ها آشنا می‌شویم.

پیش نیاز هم تسلط بر php (نحوه تعریف متغیر و کار با توابع و ...)

برای شروع برای کار با عبارات منظم به ۲ چیز نیازمند هستیم:

۱-توابع موجود و کار با آنها

۲- الگوها

حال فرض کنیم یک متغیر داریم به اسم $myVar حال می خوایم چک کنیم ببینیم که برای مثال عبارت virgool درونش هست یا نه.

تابع

preg_match()

این تابع یک الگو می گیره و با عبارتی که بهش می دید شروع میکنه به جست و جوی الگو, اگر الگو پیدا شد درست و در غیر این صورت نادرست رو برمی گردونه.

این تابع ۵ پارامتر میگیره که ۲ تاش اجباری و ۳ تاش اختیاری هست.

اولین پارامتر الگو هست .

دومین پارامتر عبارتی که باید توش جست و جو رو انجام بده.

سومین پارامتر جست و جوی های پیدا شده رو توی خودش نگه می داره.

چهارمین پارامتر اگر مقدار دهی بشه برای هر جست و جوی یافت شده عبارت آفست رو بر میگردونه.

پنجمین پارامتر می تونید بگید جست و جو رو از کجای رشته شروع کنه(پیش فرض از اول رشته شروع می کنه).

خب حالا برنامه بالا رو می خوایم به کد تبدیل کنیم.

به کد زیر توجه کنید:

$myString = &quothello word . I'm virgool:D . my favorite site is virgool.io . I'm member of virgool. "
$pattern = &quot/virgool/"
if(preg_match($pattern,$myString))
   echo &quotI found virgool"
else
  echo &quotvirgool not found"  

اگر قطعه کد بالا رو اجرا کنید خروجی I found virgool خواهید داشت.

عبارات منظم باید بین دو / / و یا # # و یا @ @ باید قرار بگیرند و جزیی از آن هستند.

در کد بالا ما به تابع preg_match() گفتیم درون رشته $myString بگرد و ببین $pattern وجود داره یا نه . تابع اگر عبارت رو پیدا کنه مقدار true برمیگردونه در غیر این صورت false که با استفاده ازدستور if می تونیم کنترل کنیم.

حال فرض کنید می خواهیم علاوه بر آن, عبارات پیدا شده رو توی متغیری قرار بده (همیشه الگو اینقدر ساده نیست و ممکن هست بخوایم عباراتی رو برامون پیدا کنه. برای نمونه یکی از مثال ها می تونه پیدا کردن سایت های روی سرور باشه که باید همه سایت هارو با الگو پیدا کنیم که بعد استفاده کنیم)

خب برای این کار باید پارامتر سوم هم وارد کنیم.

به کد زیر توجه کنید :

$myString = &quothello word . I'm virgool:D . my favorite site is virgool.io . I'm member of virgool. "
$pattern = &quot/virgool/"
if(preg_match($pattern,$myString,$occurs))
   print_r($occurs);
else
  echo &quotvirgool not found"

اگر کد بالا رو اجرا کنید خروجی شبیه خروجی زیرخواهید داشت

Array ( [0] => virgool )

با کمال تعجب شما انتظار داشتید که هر سه virgool رو پیدا و توی خروجی نشون بده ولی اینطور نشد چرا؟ به دلیل تابع preg_match() هست که اولین رو بر می گردونه.( بعد با تابع دیگری آشنا می شویم که این مشکل را برطرف می کند)

کد زیر هم خروجی مشابه رو داره

$myString = &quothello word . I'm virgool:D . my favorite site is virgool.io . I'm member of virgool. "
$pattern = &quot#virgool#"
if(preg_match($pattern,$myString,$occurs))
   print_r($occurs);
else
  echo &quotvirgool not found"

و یا

$myString = &quothello word . I'm virgool:D . my favorite site is virgool.io . I'm member of virgool. "
$pattern = &quot@virgool@"
if(preg_match($pattern,$myString,$occurs))
   print_r($occurs);
else
 echo &quotvirgool not found"

خب شاید به این فکر باشید که همیشه الگو ها اینقدر ساده و ابتدایی نیستند و ممکن هست پیشرفته تر باشند اونوقت چه باید کرد؟ خوشبختانه php این توانایی رو به صورت پیشرفته در اختیار ما قرار میده برخی از عبارات برای php یک مفهوم خاص دارند (مانند // که استفاده می کردیم برای الگو) که در زیر توضیح مختصر میدم

.

در الگو به معنای این است که هر کاراکتری می تواند ظاهر شود(فقط یک کاراکتر).

*

در الگو به این معناست که عبارت قبل از آن می تواند 0 بار یا بیشتر تکرار شود.

+

در الگو به این معناست که عبارت قبل از آن می تواند 1 بار یا بیشتر تکرار شود.

?

در الگو به معنای این است که عبارت قبل از آن می تواند ظاهر نشود یا 1 بار ظاهر شود.

{num}

عبارت قبل از این به تعداد num باید تکرار شود نه بیشتر و نه کمتر(num یک عدد صحیح است).

{m,n} 

عبارت قبل از این به تعداد حداقل m و حداکثر بار باید تکرار شود نه بیشتر و نه کمتر(n , m هردو اعداد صحیح هستند).

()

هر عبارتی بین پرانتز قرار گیرد به عنوان یک واحد حساب می شود.

[]

یک کلاس کاراکتر را مشخص می کند به این معنا که فقط یکی از کاراکتر های تعریف شده داخل آن می توانند ظاهر شوند.

- 

در الگو برای مشخص کردن محدوده به کار می رود مثلا 9-0.

^ 

دو حالت می تواند داشته باشد 1.در ابتدای الگو به این معناست که عبارت مورد جستجو باید با عبارتی (کلمه،کاراکتر یا کلاس کاراکتر) که بعد از ^ می آید شروع شود.در داخل [] به این معناست که کاراکتر بعد از آن نباید ظاهر شود.

$ 

در پایان الگو به این معناست که عبارت مورد جستجو باید با عبارتی(کلمه،کاراکتر یا کلاس کاراکتر) که قبل از $ می آید شروع شود.

|

یک عملگر است و به معنای یا می باشد.

برگرفته از http://barnamenevis.org/forum.php

اینارو چون توی سایت برنامه نویس خوب توضیح داده بود دیگه از همونجا کپی کردم.

حالا بریم سراغ مثال ها

مثال

.abcd

شامل همه کلمات

 babcd habcd kabcd 2abcd #abcd

و … میشه

یعنی هر عبارتی که با یک حرف ( هر حرفی , چه عددی چه کاراکتر) که بلافاصله بعد از آن abcd آمده باشد را شامل می شود.

مثال

abc*

شامل همه کلمات

 abcc abccc ab abcccc

و .. میشه

یعنی هرعبارتی که با ab شروع و بعد از به تعداد دلخواه ( ۰ یا هرچند) c آمده باشد را شامل می شود.

مثال

abc+

شامل همه کلمات

 abcc abccc abcccc

و .. میشه. فرق این با بالایش اینه که توی این حتما باید حداق یک c رخ داده باشد و مثل قبل دیگه شامل ab نمی شود.

یعنی هرعبارتی که با abc شروع و بعد از به تعداد دلخواه ( ۰ یا هرچند) c آمده باشد را شامل می شود.

مثال

abc?

شامل کلمات abc و ab می شود.

یعنی هر عبارتی که با ab شروع شده باشد و بعداز آن صفر یا یک c آمده باشد را شامل می شود.

مثال

abc{5}

عبارت abccccc را شامل می شود.

یعنی هر عبارتی که با ab شروع شود و بعد از آن دقیقا ۵ تا c ظاهر شده باشد را شامل می شود.

مثال

abc{2,5}

همه عبارات

 abcc abccc abcccc abccccc

را شامل می شود.

یعنی هر عبارتی که با ab شروع شده باشد و بعد از آن حداقل ۲ و حداکثر ۵ تاc ظاهر شده باشد را شامل می شود.

مثال

ترکیبی از پرانتز و عباراتی که بالا توضیح دادیم

(ab)*

همه عبارات

 ab abab ababab abababab

و … را شامل می شود

یعنی هر عبارتی که در آن ab از ۰ تا بی شمار تکرار شده باشد را شامل می شود.

مثال

ترکیبی از براکت و عباراتی که بالا توضیح دادیم

[ab]+

شامل

 a b aa bb aaa bbbbb

و … می شود.

یعنی هر عبارتی که در آن تکرار یکی از حروف a و یا b در آن حداقل یک بار ظاهر شده باشند را شامل می شود

مثال اول

^ab

شامل

  abc abcd abcc abcde

و... می شود

یعنی هر عبارتی که با ab شروع شده باشد (باید با ab شروع شده باشه)

مثال دوم

[^ab]

شامل

 e f h g  d g

و... می شود.

یعنی هر چیزی به جز یکی از دو حرف a و یا b .

مثال

ab$

شامل

 aab xab jkjsdab aslkdjlkab

و... می شود.

یعنی هر چیزی که با ab پایان یافته باشد را شامل می شود.

مثال

[a|b|c]

شامل a b c می شود.

یعنی یکی از حروف a و یا b ویا c را شامل می شود.

خب با این کاراکتر های ویژه می توانیم الگو های پیشرفته تری بسازیم که بعد کمی توضیح میدم.

کاراکتر های ویژه دیگه هم هستند که به صورت کامل و یک جا توی عکس زیر مشاهده خواهید کرد.

خب اول یک سری توابع دیگه رو میگم و بعد مثال حل می کنیم ( توابع رو از خود سایت رسمی کپی می کنم و توضیح میدم)

تابع

mixed preg_replace ( mixed $pattern , mixed $replacement , mixed $subject [, int $limit = -1 [, int &$count ]] )

خب همانطور که می بینید تابع بالا ۴ تا آرگومان میگیره که ۲ تاش اختیاری هست.

پارامتر اول الگو هست پارامتر دوم چیزی که قراره جایگزین بشه و سوم هم متنی که قرار جایگذاری توش انجام بشه.

به قطعه کد زیرتوجه کنید:

$text = &quothello world.I'm a programmer.I use php because it's very fast.I enjoy it ;) . php is fast and user freindly."
echo preg_replace(&quot/php/&quot,&quotperl&quot,$text);

اگر کدبالارو اجرا کنید خروجی شبیه خروجی زیر خواهید داشت.

hello world.I'm a programmer.I use perl because it's very fast.I enjoy it ;) . perl is fast and user freindly.

تابع

array preg_split ( string $pattern , string $subject [, int $limit = -1 [, int $flags = 0 ]] )

این تابع هم الگویی می گیره و براساس اون اطلاعات رو جدا میکنه.

تابع ۴ پارامتر داره که ۲ تاش اختیاری هست.

پارامتر اول الگو و پارامتر دوم هم متنی که باید جدا بشه.

به قطعه کد زیر توجه کنید:

$text = &quothello world.I'm a programmer.I use php because it's very fast.I enjoy it ;) . php is fast and user freindly."
print_r(preg_split(&quot/\./&quot,$text));

اگر کد بالا رو اجرا کنید خروجی شبیه زیر خواهید داشت

Array ( [0] => hello world [1] => I'm a programmer [2] => I use php because it's very fast [3] => I enjoy it ;) [4] => php is fast and user freindly [5] => )  

دقت کنید اگر توی الگو به جای \. می نوشتیم . خروجی زیر داشتیم

Array ( [0] => [1] => [2] => [3] => [4] => [5] => [6] => [7] => [8] => [9] => [10] => [11] => [12] => [13] => [14] => [15] => [16] => [17] => [18] => [19] => [20]...=> [102] => [103] => [104] => [105] => [106] => )

چون . یک کاراکتر ویژه محسوب میشه و اگر می خواید همون دات خالی معنی بده باید اونو با \ اسکیپ کنید .

خب کد زیر رو اگر اجرا کنید خروجی چی خواهد بود ؟

$text = &quothello world.I'm a programmer.I use php because it's very fast.I enjoy it ;) . php is fast and user freindly. php has a interpreter. php codes start with <?php and end with ?>  "
preg_match(&quot/php\s[a-z]?/&quot,$text,$array);
print_r($array);

مگر جز خروجی زیر دارا خواهد بود ؟

Array ( [0] => php b )  

اما واقعا فقط یک php وجود داره که بعدش یک خط فاصله و یک حرف کوچک آمده باشه ؟

تابع

int preg_match_all ( string $pattern , string $subject [, array &$matches [, int $flags = PREG_PATTERN_ORDER [, int $offset = 0 ]]] )

مانند تابع preg_match() ولی این تابع همه رخ داد هارو بر میگردونه کد بالا رو به کد زیر تبدیل میکنیم

$text = &quothello world.I'm a programmer.I use php because it's very fast.I enjoy it ;) . php is fast and user freindly. php has a interpreter. php codes start with <?php and end with ?>  "
preg_match_all(&quot/php\s[a-z]?/&quot,$text,$array);
print_r($array);

خروجی شبیه خروجی زیر خواهید داشت :

Array ( [0] => Array ( [0] => php b [1] => php i [2] => php h [3] => php c [4] => php a ) )  

همونی که انتظار داشتیم . این تابع همه رخ داد های الگو رو پیدا میکنه.