رگولار اکسپرژن

saalek110

Well-Known Member
| (یا):
اگر خاطرتان باشد گفتیم که علامت - در دستورات با قاعده به معنی "تا" است، حال می خواهیم علامت دیگری را معرفی کنیم که به معنی "یا" است، به طور مثال a|b یعنی یا a یا b، به مثال زیر توجه کنید:
PHP:
<?php
$str = 'Iran is a beautiful country.';
$check = preg_match('/Iran|Tajikistan/', $str, $match);
echo $match[0]
?>
خروجی مثال بالا Iran خواهد بود، با توجه به دستور Regex اگر به جای Iran عبارت Tajikistan نیز وجود داشت، دستور معتبر بود و Tajikistan به عنوان خروجی چاپ می شد.
 

saalek110

Well-Known Member

حروف خاص در عبارات با قاعده


تا این قسمت از آموزش، با کاراکترهای پرکاربرد در دستورات Regular Expressions آشنا شدیم، اما بخشی از مفاهیم این زبان جالب با استفاده از حروف خاصی تعریف می شود که در زیر به صورت تیتروار، لیست برخی از پر کاربردترین آنها را به همراه مثال با هم مرور می کنیم.
 

saalek110

Well-Known Member
حرف d\
حرف d\ (حروف کوچک) به معنی هر عددی (d مخفف digit)، مثال:
PHP:
<?php
$str = 'tel: +98';
$check = preg_match('/^tel: \+(\d+)/', $str, $match);
print_r($match);
?>
خروجی:

کد:
Array
(
    [0] => tel: +98
    [1] => 98
)
نکته 1: پیش تر گفتیم که علامت \ کاراکترهای دستوری را به حالت عادی تبدیل می کند، اما در اینجا برعکس حالت قبل، علامت \ کاراکترهای عادی را به دستور تبدیل می کند (d یک حرف عادی است، اما d\ یعنی هر عددی).
نکته 2: بزرگ یا کوچک بودن حروف خاص در عبارات با قاعده، ممکن است بر روی مفهوم آنها اثرگذار باشد.
 

saalek110

Well-Known Member
حرف D\
حرف D\ (حروف بزرگ) به معنی هر کاراکتری که عدد نباشد، مثال:
PHP:
<?php
$str = 'tel: +98W50';
$check = preg_match('/^tel: \+.*(\D+).*/', $str, $match);
print_r($match);
?>
خروجی:
کد:
Array
(
    [0] => tel: +98W50
    [1] => W
)
نکته: تمام مثال ها فرضی و صرفا جهت درک راحت تر مطالب ارائه شده اند، لذا ممکن است برخی مواقع عادی به نظر نرسند!
 

saalek110

Well-Known Member
حرف W\
حرف W\ به معنی هر کاراکتری که حرف الفبایی یا عدد نباشد، مثال:
PHP:
<?php
$str = 'P21#W@RR^';
$check = preg_match('/.*(\W+).*(\W+).*(\W+)/', $str, $match);
print_r($match);
?>
خروجی:
کد:
Array
(
    [0] => P21#W@RR^
    [1] => #
    [2] => @
    [3] => ^
)
 

saalek110

Well-Known Member
حرف s\
حرف s\ به معنی هر فضای خالی (Whitespace)، مثال:
PHP:
<?php
$str = 'Hello World!';
$check = preg_match('/(\w){1}.*\s(\w){1}.*/', $str, $match);
print_r($match);
?>
خروجی:
کد:
Array
(
    [0] => Hello World!
    [1] => H
    [2] => W
)
 

saalek110

Well-Known Member
حرف S\
حرف S\ به معنی هر کاراکتری که فضای خالی نباشد، مثال:
PHP:
<?php
$str = 'Hello World!';
$check = preg_match('/(\S+)\s(\S+)/', $str, $match);
print_r($match);
?>
خروجی:
کد:
Array
(
    [0] => Hello World!
    [1] => Hello
    [2] => World!
)
 

saalek110

Well-Known Member
Modifiers در Regular Expressions
اگر به نکاتی که در خلال آموزش به صورت پراکنده به آن اشاره شد، توجه کرده باشید، سه مورد در کدهایی که تا این لحظه نوشتیم خودنمایی می کند:
- کدها به حروف بزرگ یا کوچک حساس هستند، به طور مثال [a-z] الزاما شامل حروف کوچک می شود.
- دستور . (هر کاراکتری) شامل خط جدید (line break) نمی شود، به طور مثال کد زیر عدد 0 یا FALSE را برمی گرداند:

PHP:
<?php
$str = 'Reg
ex is not too difficult!';
$check = preg_match('/Re.ex/', $str);
echo $check;
?>
مشکل از آنجا نشات می گیرد که مقادیر متغیر فرضی str با یک خط جدید شکسته شده.
- اگر بخواهیم با علامت های ^ و $، ابتدا و انتهای رشته را مشخص کنیم، در حالتی که مقادیر رشته از چندین خط جدید تشکیل شده باشد، به مشکل بر خواهیم خورد.
راه حل مشکلات بالا در دستورات با قاعده، استفاده از تغییر دهنده ها یا Modifiers است، Modifiers چیزی نیستند جزء چند حرف خاص که در انتهای دستور قرار می گیرند و رفتار آن را تغییر می دهند.
 

saalek110

Well-Known Member
modifier i
برای نادیده گرفتن بزرگ یا کوچک بودن حروف، از تغییر دهنده i (برگرفته از case-insensitive) استفاده می کنیم، به طور مثال:
PHP:
<?php
$str = 'Hello World!';
$check = preg_match('/[a-z\s\W]*/i', $str, $match);
print_r($match);
?>
خروجی:
کد:
Array
(
    [0] => Hello World!
)
 

saalek110

Well-Known Member
modifier s
برای محاسبه خط جدید در هنگامی که از کاراکتر دستوری . استفاده می کنیم، تغییر دهنده s (برگرفته از single line) کاربرد دارد، مثال:
PHP:
<?php
$str = 'Reg
ex is not too difficult!';
$check = preg_match('/Re.+ex/s', $str);
echo $check;
?>
خروجی برابر 1 یا TRUE خواهد بود.
نکته: در این حالت خود خط جدید نیز یک کاراکتر محسوب شده، لذا درج علامت + (یک تکرار یا بیشتر) بعد از . ضرورت دارد.
 

saalek110

Well-Known Member
modifier m
برای اعمال دستورات عبارات باقاعده به صورت خط به خط، تغییر دهنده m (برگرفته از multiline) کاربرد دارد، به عبارتی استفاده از این تغییر دهنده باعث می شود تا دستور ما در رشته هدف، به جای بررسی عادی، برای هر خط به صورت جداگانه بررسی شود، مثال:
PHP:
<?php
$str = 'CSS
JavaScript
PHP
HTML
MySQL';
$check = preg_match('/^(HTML)/m', $str, $match);
print_r($match);
?>
خروجی:
کد:
Array
(
    [0] => HTML
    [1] => HTML
)
اما اگر همین کد را بدون m استفاده کنیم، نتیجه ای نخواهیم داشت:
PHP:
<?php
$str = 'CSS
JavaScript
PHP
HTML
MySQL';
$check = preg_match('/^(HTML)/', $str, $match);
print_r($match);
?>
خروجی:
کد:
Array
(
)
نکته: منظور از خط، در واقع همان کاراکتر (نامرئی) n\ یا r\ است.
 

saalek110

Well-Known Member
در پایان این آموزش باید یادآور شویم که دستورات مربوط به عبارات با قاعده به موارد گفته شده محدود نمی شوند، اما برای برنامه نویسی وب دانستن همین اصول و مفاهیم پر کاربرد، لازم و تا حد زیادی کافی خواهد بود.

سالک: کپی از:


با تشکر از تهیه کننده این مقاله.
 

saalek110

Well-Known Member
حال ممکن است این سوال برای شما پیش بیاید که اگر ما بخواهیم در نام کاربری خود، حروف پارسی نیز داشته باشیم چگونه آنرا در رجکس تعریف کنیم. برای این کار، باید فرمت یونیکد کاراکتر هایی که می خواهید را پیدا کنید. بعنوان مثال:

[\u0600-\u06FF]

کلاس کاراکتر فوق، معرف حروف الف تا ی می باشد. و شامل گ چ پ ژ نیز هست. بازه ی زیر معرف اعداد عربی است (مانند ۳):

[\u0660-\u0669\u06F0-\u06F9]

جدول کامل کاراکتر های عربی در این پیج موجود است:


نقل از:
 

saalek110

Well-Known Member
PHP:
<?php

$userName = isset($_POST['username']?mysql_real_escape_string($_POST['username']):'');
if($userName){
    $pattern = '/^[a-z0-9_-]{3,16}$/'
    $output = preg_match($pattern,$userName);
    if($output){
        echo 'Username complies the pattern!';
    }
}

?>

همانطور که در کد فوق می بینید، ابتدا به متغیر $userName مقدار می دهیم و سپس با دستور preg_match آنرا با الگوی نام کاربری تطبیق داده و اگر مطابق بود، پیام موفقیت را نمایش می دهیم.

سالک: برای حروف فارسی ، پست قبل توضیح دادیم.

نقل از:

 

saalek110

Well-Known Member
خوب، همانطور که در قسمت اول دیدید، ما هدر یک صفحه بازگشتی از یک تراکنش بانکی را دریافت کرده و می خواهیم موفقیت یا عدم موفقیت را از بین متن استخراج کنیم. این عملیات با استفاده از رگولار اکسپرشن انجام می گیرد.

اگر بیاد بیاورید، هدری که دریاقت می کردیم چیزی شبیه این بود:


HTTP/1.1 200 OK Date: Tue, 21 Oct 2008 05:32:32 GMT

خوب، می دانیم که متن ما با HTTP شروع می شود، بنابراین قدم به قدم پیش می رویم و الگو یا پترن رگولار اکسپرشن را ایجاد می کنیم:

/^HTTP$/

حال متوجه می شویم که کاراکتر بعدی اسلش است. و اسلش یک کاراکتر خاص است. همانطور که در جدول کامل علامت های رگولار اکسپرشن نشان داده شده، باید از بک اسلش برای escape کردن کاراکتر های خاص استفاده کنیم:

/^HTTP\/1.1$/

اینجا به مشکلی بر می خوریم. اگر قبلاً با هدر ها کار کرده باشید، می دانید که آنها می توانند 1.1، 1.2، 1.3 و.. باشند. پس باید الگو را جوری طرح کنیم که همۀ 1.x را پوشش دهد. برای این کار با بکسلش دی یک عدد را قرار می دهیم:

/^HTTP\/1\.\d$/

همانطور که مشاهده می کنید، نقطه هم یک کاراکتر خاص است و باید اسکیپ شود. خوب، با الگوی فوق، هدر هایی مانند HTTP/1.1، HTTP/1.2، HTTP/1.3 و غیره پیدا می شوند. اکنون باید یک فاصله را در پترن (pattern) خود قرار دهیم. این کار را بک اسلش اس انجام میدهد:

/^HTTP\/1\.\d\s$/

سپس نوبت به عدد مورد نظر ما می رسد. هدف از نوشتن پترن فقط استخراج این عدد بوده است و اکنون می توانیم انجامش دهیم. خوب، می دانیم که این یک عدد است و تعداد کاراکتر های آن 3 تاست. می توانیم این محدودیت کاراکتر را هم با {3} و هم با + پیاده سازی کنیم:
کد:
/^HTTP\/1\.\d\s\d+$/

or:

/^HTTP\/1\.\d\s\d{3}$/
خوب، اکنون، اگر با دستور preg_match چنین الگویی را روی یک متن خاص پیاده سازی کنیم، آن قسمتی از متن خروجی داده می شود که با الگو تطابق می کند. ولی اگر فرضا فقط قسمت 200 یا 404 (یعنی عدد هدر) را بخواهیم، می توانیم این عدد را درون پرانتز بگذاریم که گروه بندی شود. یعنی یک گروه ایجاد می کنیم و خروجی preg_match دیگر همۀ متن مطابق با الگو نخواهد بود، و بلکه فقط عددی که داخل گروه باشد خواهد بود:

PHP:
<?php
    $text = 'HTTP/1.2 200 blah blah...';
    $pattern = '/^HTTP\/1\.\d\s(\d{3})$/'
    $output = preg_match($pattern,$text);
    echo $output;
    //will print: 200
?>
سالک: در کد نوشته خروجی اش ۲۰۰ است.
سالک: از پترن بالا این جوری برداشت کردم که چون داخل پرانتز نوشته:

کد:
\d{3}
یعنی داره دنبال این می گرده که فکر کنم به معنی ۳ عدد پیاپی میشه.

منبع:

 

saalek110

Well-Known Member

تطابق یک عدد هگز​

عدد های هگزادسیمال با # شروع شده و دارای اعداد از 0 تا 9 و حروف از A تا D هستند. حروف آنها می تواند lowercase نیز باشد. اگر کد هگز رنگ ها را دیده باشید، می دانید که کد چیزی شبیه این است:
کد:
#FFFFFF
#fff
#cc006d
#58ff40

خوب، با دانستن این اطلاعات، فرض کنید می خواهیم یک کد رنگ که عددی هگزادسیمال است را درون متن پیدا کنیم. به پترن زیر توجه کنید:

neomarket_hex_regular_expressions.jpg

از آنجایی که کد رنگ هم می تواند 3 و هم 6 کاراکتری باشد، مجبوریم دو کلاس کاراکتر درست کنیم و آنها را با عملوند مقایسه “یا” (| پایپ) از هم جدا کنیم. علامت شارپ که در ابتدا باید باشد چون در همۀ کد های هگز وجود دارد. سپس یک گروه ایجاد می کنیم تا آنرا در خروجی داشته باشیم. و همانطور که گفتیم، دو کلاس ایجاد کرده و با | از هم جدا می کنیم. کلاس ها محدودیت کاراکتر {3} یا {6} دارند. همچنین فراموش نکنید که کاراکتر های a تا f می توانند در آن رشته باشند.


منبع:
 

saalek110

Well-Known Member
خوب، حالا به یک تطابق مهم می رسیم. تطابق یک آدرس URL. برای این، باید ابتدا بدانیم که یو آر ال ها می توانند مانند زیر باشند:

کد:
http://neomarket.ir/

http://www.google.com

https://www.google.com

http://example.com/%D9%85%D8%AA%D9%86.html

http://www.example.com/this_is_an_article.php
خوب. کار مسلما پیچیده تر از مثال های قبلی می باشد. آدرس ها هم می توانند با http شروع شوند و هم با https. و حتی بعضی آدرس ها می توانند با ftp یا پروتکل های دیگر شروع شوند. برای سادگی فقط http و https را در نظر می گیریم:

/^(https?)$/

همانطور که می بینید، علامت سوال باعث می شود که s قسمت اول اختیاری باشد. یعنی اگر وجود نداشته باشد هم تطابق شکل می گیرد.

/^(https?):\/\/(www\.)?([a-z0-9.-]+)\.([a-z]{2,4})\/?([\/a-zA-Z0-9-_%\.\?=]*)?\/?$/

با بررسی پترن فوق، مشاهده می کنیم که پس از چک کردن http یا https، کالن دابل اسلش چک می شوند. سپس یک گروه ایجاد می شود که .www را در آن بررسی می کند. علامت سوال اطمینان ایجاد می کند که این گروه اختیاری است. سپس یک کلاس خواهیم داشت که نام دامین شما خواهد بود. و نقطه و پسوند سایت (دات کام، دات نت و..) که می تواند بین 2 تا 4 کاراکتر باشد. سپس اسلش اختیاری و ادامه ی لینک چک می شوند. ستاره می گوید که ادامه ی لینک می تواند صفر یا بیشتر باشد و می تواند شامل کاراکتر های مختلفی مانند / _ – % = ؟ و.. باشد.

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

saalek110

Well-Known Member

تمرین بعدی: تطبیق IP آدرس​

حتما می دانید که 127.0.0.1 یک آدرس آی پی است. همچنین 10.111.222.333.

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

ip_regular_expressions_pattern.jpg


PHP:
/^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/


پرانتز اول شامل یک پرانتز دیگر است. این پرانتز هایی که با علامت سوال کالن شروع می شوند، non-capturing group هستند. یعنی مقداری بر نمی گردانند. در پرانتز داخلی بررسی می شود که اولین عدد شبیه 254 یا 255 باشد و عدد 256 مورد قبول نباشد. یا اینکه یک عدد سه رقمی باشد که اولش 20 و 21 و 22 و 23 و24 باشد. یا شبیه 123 یا 039 باشد. دو تا از رقم ها نیز اختیاری هستند. و سپس باید نقطه آمده باشد تا این گروه عمل کند. {3} تعیین می کند که سه تا از این گروه ها باید در متن وجود داشته باشند. تنها تفاوت این گروه با گروه بعدی عدم وجود نقطه است. گروه آخر نباید نقطه داشته باشد. یعنی اگر وجود داشته باشد جزو پترن نخواهد بود.
 

saalek110

Well-Known Member

تمرین آخر: پیدا کردن تگ های اچ تی ام ال HTML​

در پایان، به پیدا کردن تگ های اچ تی ام ال می پردازیم که یکی از کاربرد های مهم رگلار اکسپرشن می باشد.


PHP:
/^<([a-z]+)([^<]+)*(?:>(.*)<\/\1>|\s+\/>)$/


html_tag_regex_neomarket.jpg

بخش اول نشان می دهد که تگ باید با > شروع شود و در آن می تواند حروف یا هر علامتی بجز < وجود داشته باشد. علامت ها اختیاری هستند. ولی حروف اختیاری نیستند. یعنی تگ نباید خالی باشد. سپس، باید علامت < اتفاق بیوفتد. این نشان می دهد که opening tag تمام شده است و باید اکنون یک رشته متنی را دریافت کنیم. پرانتزی که دات ستاره دارد این کار را انجام می دهد. ستاره نشان می دهد که این بخش هم اختیاری است. سپس > دوباره باید اتفاق بیوفتد. در closing tag دو اتفاق می تواند بیافتد. یا با فاصله </ تمام شود یا بک اسلش و همان متن opening تگ و < بیاید. متغیر پرانتز اول را با عدد 1 نشان می دهیم. پس اگر بک اسلش 1 و < داشته باشیم، مطمئن خواهیم بود که تگ بسته شده است.
این تمرین ها را در ابزار آنلاین ریجکس تست کنید:


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

برای تمرین های بیشتر:

 

جدیدترین ارسال ها

بالا