تمرین هایی برای یادگیری رگولار اکسپرشن
نوامبر 7, 2014
بردکرامب Breadcrumb چیست؟
نوامبر 12, 2014
نمایش همه

رگولار اکسپرشن قسمت دوم

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

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

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

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
	$text = 'HTTP/1.2 200 blah blah...';
	$pattern = '/^HTTP\/1\.\d\s(\d{3})$/'
	$output = preg_match($pattern,$text);
	echo $output;
	//will print: 200
?>

 

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

var username = 'JamesHetfield';
alert(/[A-Za-z_-]+/.test(username)); // returns true

این پترن، همانطور که در قسمت اول بررسی کردیم، یک کلاس کاراکتر است که در آن، حروف انگلیسی A تا Z و حروف کوچک و آندر لاین و منها مجاز هستند و دیگر کاراکتر ها غیر مجاز. منظور از غیر مجاز یعنی اینکه اگر متنی داشته باشیم و آنرا با الگوی فوق چک کنیم ودر آن چیزی غیر از کاراکتر های تعریف شده در کلاس باشد، آنها به خروجی منتقل نخواهند شد.

در مثال جاوا اسکریپت فوق، تابع test(); برای شما متن را با الگو تطبیق داده و سپس خروجی boolean می دهد. یعنی اگر تطابق انجام شد، true و در غیر اینصورت false بر می گرداند.

 

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

//example 2: Split()
var str = 'my website is designed by neoMarket';
alert(str.split(/\s/)); // alerts "my, website, is, designed, by, neoMarket"

str = 'my website is designed by neoMarket';
alert(str.split(/\s/)[3]); // alerts "designed"

در مثال فوق، تابع جاوا اسکریپتی split با استفاده ازرگولار اکسپرشن یک متن را به چند عضو تقسیم می کند و یک آرایه از اعضا می سازد. جدا سازی با استفاده از الگوی بک اسلش s می باشد که بمعنی جداسازی با استفاده از space می باشد. در قسمت دوم این مثال، چهارمین عضو از آرایه آلرت می شود که معادل است با کلمه ‘designed’.

خوبی جاوا اسکریپت این است که می توانیم با استفاده از alert با یک صفحه html ساده رگولار اکسپرشن را تست کنیم. اگر از گوگل کروم استفاده می کنید، خطا های جاوا اسکریپت را می توانید در inspect element مشاهده کنید.

خوب، مثال بعدی، استفاده از تابع replace جاوا اسکریپت می باشد.

//example 3: Replace()
var someString = 'Hello, World';
someString = someString.replace(/World/, 'Universe');
alert(someString); // alerts "Hello, Universe"

username = 'A;minVanda;@%';
username = username.replace(/[^A-Za-z\d_-]+/, '');
alert(username); // AminVanda;@%

username = 'Ja;sonStatham;@%';
username = username.replace(/[^A-Za-z\d_-]+/g, '');
alert(username); // alerts JasonStatham

در مثال فوق، تابع replace می آید و کلمه world را با Universe جایگزین می کند.

در بخش بعدی، فرض می کنیم که کاربر نام کاربری برای خود وارد کرده است و پیش از زبان های server side می خواهیم آنرا با جاوا اسکریپت که client side است بررسی کنیم. هدف زدودن همه ی کاراکتر های غیر مجاز بوده و اجازه دادن فقط به حروف بزرگ و کوچک و آندرلاین و منها (هایفن hyphen) می باشد. همانطور که مشاهده می کنید، کلاسی از کاراکتر ها ایجاد شده و کاراکتر های مجاز تعریف شده اند. همانطور که می دانید، علامت سرمفلکس (^) اگر داخل کلاس باشد به معنی NOT می باشد. پس اگر در لابلای متنی که از کاربر جهت username می گیریم کاراکتر های دیگری مثل ; / \ & ) * > و.. باشند، با متن تهی جایگزین خواهند شد. ولی اگر توجه کنید، می بینید که فقط اولین کاراکتر اضافی جایگزین شده است و بقیه ی کاراکتر های اضافی از فیلتر عبور کرده اند.

بخاطر همین، در قسمت آخر از مثال فوق، مثال تکرار شده است با این تفاوت که در انتهای الگوریتم رگولار اکسپرشن، یک g قرار داده شده است. این کار به جاوا اسکریپت می گوید که متوقف نشو و جستجو را ادامه بده تا انتهای متن. g معرف global می باشد. همانطور که می بینید، با حضور پرچم g در انتهای رگولار اکسپرشن (پس از فوروارد اسلش انتهایی)، موتور مفسر به عملیات الگو یابی خود ادامه خواهد داد.

خوب، به عنوان آخرین مثال javascript در آموزش رگولار اکسپرشن، تابع match را معرفی خواهیم کرد:

//example 4: Match()
var name = 'TonyMontana';
alert(name.match(/o/)); // alerts "o"

var name = 'TonyMontana';
alert(name.match(/o/g)); // alerts "o,o"

var name = 'TonyMontana';
alert(name.match(/o/g)[0]); // alerts "o"

var string = 'This is just a string with some 12345 and some !@#$ mixed in.';
alert(string.match(/[a-z]+/gi)); // alerts "This,is,just,a,string,with,some,and,some,mixed,in"

var string = 'This is just a string with some 12345 and some !@#$ mixed in.';
var matches = string.match(/[a-z]+/gi);
alert(matches[2]); // alerts "just"

خوب، تنها تفاوت تابع match در جاواسکریپت این است که این تابع خود متن تطابق داده شده را بر می گرداند بجای true و false. خودتان مشاهده می کنید که در قسمت نخست از مثال فوق، خروجی حرف o می باشد. در دومین بخش، (بعلت وجود g در انتها) یک آرایه دو عضوی که هر دو o هستند برگشت داده می شود. و سومین بخش، عضو نخست از آرایه برگشت داده می شود.

 

اکنون بیایید بعنوان جمع بندی از 4 مثال جاواسکریپت فوق، یک تمرین انجام دهیم. فرض کنید الگویی می خواهیم که با آن قسمت های مختلف یک ایمیل آدرس بدست بیایند. یعنی اگر my.email@gmail.com داشته باشیم، my.email و gmail را جداگانه بدست بیاوریم.

خوب، پیش از هر چیز می دانیم که یک ایمیل از 3 قسمت تشکیل شده است: firstPart@secondPart.thirdPart قسمت اول آدرس ایمیل، قسمت دوم دامینی که به شما سرویس ایمیل داده است و با علامت @ از قسمت اول جدا شده است.. و نهایتا قسمت سوم که معمولا دات کام است یا دات نت یا دات ارگ و.. و در این مثال به کار ما نمی آید.

خوب، ابتدا باید یک کاراکتر کلاس درست کنیم که قسمت اول را بدست بیاوریم:

//firstPart has: a to z, digits, underscore and hyphen
/[a-z\d_-]+/

//grouping:
/([a-z\d_-]+)/

//adding @ and the secondPart:
/([a-z\d_-]+)@([a-z\d_-]+)/

//adding a dot and the thirdPart (no need to group the 3rd part):
/([a-z\d_-]+)@([a-z\d_-]+)\.[a-z]{2,4}/

خوب، تمرین فوق به خوبی به شما نشان می دهد که این الگو چگونه شکل می گیرد.

ابتدا firstPart را ایجاد می کنیم. یک کاراکتر کلاس است که از حروف لوورکیس (lowercase) و آندرلاین و هایفن ساخته می شود.

سپس علامت @ گذاشته و قسمت secondPart را اضافه می کنیم. این قسمت نیز مانند قسمت اول ایمیل می باشد.

نهایتاً دات اضافه می کنیم (که با بک اسلش escape می شود) و قسمت آخر thirdPart را اضافه می کنیم. این قسمت خوشبختانه دارای مشخصاتی هست. مثلا، بین سه تا چهار کاراکتر است و دارای هیچ کاراکتری جز حروف کوچک نیست. بخاطر همین حروف a تا z بین 2 تا 4 کاراکنر تعریف شده است.

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

var email = 'info@neomarket.ir';
alert(email.replace(/([a-z\d_-]+)@([a-z\d_-]+)\.[a-z]{2,4}/ig, '$1, $2')); // alerts "info, neomarket"

//i is to ignore case and g is for global

همانطور که می بینید، متغیر های 1 و 2 هر کدام یکی از اعضای آرایه را خواهند داشت و به خروجی منتقل خواهند کرد.

i د ر انتهای پترن اکسپرشن، به این معنی است که کیسینگ نادیده گرفته شود (ignore). یعنی http با HTTP فرقی نداشته باشد.

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

قسمت سوم و پایانی

 

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

4.3/5 - (7 امتیاز)
امین بهداروند
فارغ التحصیل کارشناسی برق مخابرات هستم. هم اکنون بعنوان کارشناس تجهیزات فیبر نوری و مخابراتی فعالیت می کنم. به زمینه های دیگر شامل برنامه نویسی vb.net و PHP و MySQL و همچنین طراحی وب سایت، طراحی گرفیکی و بازی سازی سه بعدی، بلاگ نویسی، موسیقی و... نیز علاقه مند هستم.

8 دیدگاه ها

  1. nimarasi گفت:

    مهندس ممنون خیلی عالی بود

  2. ali گفت:

    خوب بود
    تشکر

  3. mostafa گفت:

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

  4. حبیب گفت:

    ممنون از زحمات شما در تهیه این آموزش بسیار مفید و کاربردی
    واقعاً خیلی خوب و روان توضیح دادید. بازهم ممنون

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد.