عبارات منظم (Regular expressions)، ابرقهرمانانی هستند که با کمک گرفتن از الگوها به ما کمک میکنند ترکیبات خاص از کاراکترها را در بین رشتهها پیدا کنیم. الگوها در زبان برنامه نویسی جاوا اسکریپت بهعنوان شیء شناخته میشوند که با استفاده از متدهای مختلف اشیاء Regexp و String مانند exec() ،test() ،match() ،matchAll() ،replace() ،replaceAll() ،search() و split() وظایف گوناگونی را بهعهده میگیرند. در این مقاله از آموزش عبارات منظم در جاوا اسکریپت با Regular expressions و نحوهی تسلط بر آنها، آشنا خواهید شد.
نحوه ساختن عبارات با قاعده (Regular expression)
در برنامه نویسی جاوا اسکریپت برای تطبیق متن با استفاده از الگوهای خاص از عبارتهای با قاعده یا رگولار اکسپرشن استفاده میکنیم. در آموزش عبارات منظم در جاوا اسکریپت دو روش برای ساخت آنها وجود دارد که عبارتاند:
۱. استفاده از لیتِرال رگولار اکسپرشن: در این روش از علامت “/” در دو طرف الگوی مورد نظر استفاده میشود. استفاده از این روش باعث میشود، الگو در زمان بارگذاری اسکریپت کامپایل به کد قابل اجرا تبدیل شود. گفتنی است که این روش به بهبود عملکرد برنامه کمک میکند.
const re = /ab+c/;
۲. فراخوانی تابع سازنده شی Regexp: در این روش از تابع سازنده شی در جاوا اسکریپت استفاده میشود. Regexp کمک میکند تا الگو در زمان اجرای برنامه، کامپایل شود. این روش زمانی که الگو در حال تغییر است با الگو از منبع دیگری مانند ورودی کاربر گرفته میشود، استفاده خواهد شد.
const re = new RegExp("ab+c");
با استفاده از این دو روش در زمان برنامه نویسی، الگوهای قدرتمند برای تطبیق یا متن در برنامه خود میسازید که این امکان را میدهد تا کارهای جالب و متفاوتی انجام دهید.
پیشنهاد مطالعه: آموزش متد Includes در جاوا اسکریپت
نوشتن الگوی رگولار اکسپرشن
الگوهای Regular expression، ترکیبی از کاراکترهای ساده یا کاراکترهای ساده خاص هستند. برای مثال میتوان گفت الگوی سادهی “/abc/”زیرمجموعه دقیق “abc” را در متن جستجو میکند و اما پیدا کردن الگوی “/Chapter (\d+).\d/” کمی پیچیده است و از کارکترهای خاص برای پیدا کردن موارد دقیقتر استفاده شده است.
در این آموزش عبارات منظم در جاوا اسکریپت با انواع الگوهای Regex در Javascript آشنا میشوید که شامل موارد زیر هستند:
استفاده از الگوهای ساده
الگوهای ساده در رگولار اکسپرشن، کاراکترهایی هستند که قصد داریم بهصورت مستقیم مطابقت آنها را در پیدا کنیم. بهعنوان مثال الگوی “/bca/” زمانی با ترکیب حروف در متن مطابقت پیدا میکند که ترکیب و ترتیب قرارگیری کاراکترها درست مانند “bca” باشد.
استفاده از کاراکترهای خاص
از کاراکترهای خاص، زمانی استفاده میشود که بهدنبال تطابقی بیشتر از یک زیر مجموعه ساده هستیم. برای مثال میتوان گفت برای پیدا کردن حرف “a” که پس از آن تعداد مشخصی از حرف “b” باشد سپس حرف “c” در متن قرار داشته باشد از الگوی “/ab*c/” باید استفاده کرد. علامت * که پس از حرف b آمده است نشاندهند تعداد صفر یا هر تعداد دلخواهی از این کاراکتر است. در نهایت خروجی این الگو میتواند در جمله “cbbabbbbcdebc” زیر مجموعهی “abbbbc” باشد.
راهنمای آموزش عبارات منظم در جاوا اسکریپت
تا اینجا با الگوهای رگولار اکسپرشن آشنا شدیم، حالا باید با نحوهی قدرت دادن به الگوها آشنا شویم. برای انجام این کار از راهنماهای مختلفی استفاده میشود که به دقیقتر شدن و انعطافپذیری بیشتر جستجوها کمک میکند.
این الگوهای عبارات منظم در جاوا اسکریپ ریجکس عبارتاند از:
- راهنمای محدودهها (Assertions): با استفاده از این محتوا میتوان مشخص کرد که الگو چگونه شروع شود و پایان یابد. یعنی میتوان برای آن شرطهایی گذاشت که الگو را از ابتدای خط، ابتدای کلمه، انتهای خط، انتهای کلمه یا هر شرط دیگری گذاشت. این راهنما نشان میدهد که چه چیزهایی باعث تطابق متن با الگو میشود.
- راهنمای کلاسهای کاراکتر (Character Classes): با کمک این راهنما میتوان بین انواع کاراکترها تمایز ایجاد کرد. یعنی میتوان مشخص کرد که در متن بهدنبال عدد یا حروف الفبا هستیم. این راهنما قدرت بیشتری به الگوها میدهد و میتوان جستجوها را با هدف مشخصی انجام داد.
- راهنمای گروهها و ارجاعات پشتیبان (Groups and Backreferences): این گروهها الگوهایی هستند که امکانی فراهم میکنند تا چند الگو بهعنوان یک الگوی واحد در نظر گرفته شود. با استفاده از این الگوها میتوان اطلاعات بیشتری را برای تطبیق زیر مجموعهها در نظر گرفت.
- راهنمای کمیتسازها (Quantifiers): با راهنمای کمیتساز میتوان مشخص کرد که بهدنبال چند کاراکتر یا چند عبارت خاص هستیم.
در جدول زیر کاراکترهای خاص در آموزش عبارات منظم در جاوا اسکریپت معرفی شدهاند.
فرار کردن از عبارات منظم نظریه زبان عبارت منظم
برخی اوقات هدف برنامه نویسان در عبارات منظم نظریه زبان عبارت منظم، پیدا کردن کاراکترهای مشخص بهصورت عادی است نه یافتن مفهوم آنها در کاراکتراهای دیگر. بهعنوان مثال میتوان گفت شما میخواهید کاراکتر * را در متن پیدا کنید نه مفهومی از کاراکترهای دیگر. برای این منظور از مفهوم Escaping() به معنی فرار کردن استفاده میشود.
برای اینکه منظور خود را برسانیم علامت \ را در جلوی کاراکتر مورد نظر قرار داده تا Regular expression بهدنبال همان کاراکتر بگردد و آن را به مفهومی خاص تبدیل نکند. بهتر است این مفهوم را با مثالی دقیقتر توضیح دهیم، فرض کنید میخواهید در خروجی a*b را نمایش دهید، برای این منظور باید از دستور /a\*b/ استفاده کرد. همچنین اگر قصد دارید خود بک اسلش (\) را پیدا کنید باید از الگویی مانند /[A-Z]:\\/ استفاده کنید. زیرا بک اسلش اول میتواند بک اسلش دوم را از الگو فرار دهد.
توجه کنید، اگر از سازندهی Regexp همراه با رشته تحتالفظی استفاده میکنید، بک اسلش در این رشته مفهوم فرار را دارد. برای مثال الگوهای /a*b/ و new RegExp(“a\b”) عملکردی یکسان دارند و بهدنبال b * aمیگردند. چنانچه قصد دارید رشتههای فرار را به الگوی خود اضافه کنید باید از تابع String.prototype.replace() در الگوهای خود استفاده کنید.
function escapeRegExp(string) {
return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string
}
زمانیکه قصد دارید کل متن را جستجو کنید و تمام مواردی که با الگو مطابقت دارند را پیدا کنید باید از حرف “g” در برنامه نویسی Javascript استفاده کرد. این پرچم که بهطور کامل در آموزش عبارات منظم در جاوا اسکریپت توضیح داده میشود، کمک میکند تا کل متن بهطور دقیق بررسی شود و تمام موارد بهطور کامل پیدا شوند.
پیشنهاد مطالعه: Scope در جاوا اسکریپت چیست؟ آموزش اسکوپ به زبان ساده
وجود پرانتز در آموزش عبارات منظم در جاوا اسکریپت
زمانی که از پرانتز استفاده میشود، زیر مجموعه الگو در رشته فرعی همسان قرار گرفته و در حافظه رگولار اکسپرشن ذخیره میشود. پس از ذخیره شدن امکان استفاده از رشته فرعی در فراخوانیهای دیگر وجود دارد.
استفاده از عبارات منظم در برنامه نویسی جاوا اسکریپت
عبارات منظم با متدهای ()Regexp test و ()exec همراه با String match()، matchAll()، replace()،replaceAll()، ()search و ()split از جمله Flag در جاوا اسکریپت هستند که در جدول زیر بهطور کامل توضیح داده شدهاند:
متد | توضیحات |
()exec | در آرایه جستجو میکند و در صورت تطابق اطلاعات آن را برمیگرداند. در صورت عدم تطابق مقدار null را نشان میدهد. |
()test | این تابع بررسی میکنه که آیا یک الگو، داخل متن وجود دارد یا نه. در صورت پیدا شدن، خروجی True (درست) و در غیر این صورت مقدار False (غلط) را نمایش میدهد. |
()match | آرایهای را برمیگرداند که شامل همه موارد منطبق، از جمله گرفتن گروهها یا در صورت نبودن هیچ مطابقتی مقدار null را نشان میدهد. |
()matchAll | یک تکرار کننده حاوی همه موارد منطبق، از جمله گرفتن گروهها را برمی گرداند. |
()search | این متد عبارت را در رشته جستجو میکند و ایندکس منطبق را برگردانده. در صورت پیدا نکردن عبارت مقدار -1 را برمیگرداند. |
()replace | جستجوی یک تطابق در یک رشته را انجام میدهد و رشته فرعی منطبق را با یک زیر رشته جایگزین جایگزین میکند. |
()replaceAll | جستجوی تمام موارد منطبق در یک رشته را انجام میدهد و رشتههای فرعی همسان را با یک زیر رشته جایگزین میکند. |
()split | از یک عبارت منظم یا رشته ثابت برای شکستن یک رشته به آرایهای از رشتههای فرعی استفاده میکند. |
نحوهی پیدا کردن الگو در متن
برای اینکه بفهمیم الگو در متن وجود دارد یا خیر باید از روشهای مختلف استفاده کنیم. اگر میخواهید بدانید الگویی در متن وجود دارد یا نه، از متدهای search() یا test() میتوانید استفاده کنید. متدهای فوق سرعت زیادی دارند، اما ممکن است اطلاعات زیادی به ما ندهند.
اگر میخواهید از جزئیات الگوها نیز اطلاعات بدست آورید از متدهای exec() و match() میتوانید استفاده کنید.
مثالی برای پیدا کردن الگو در متن:
const myRe = /d(b+)d/g;
const myArray = myRe.exec("cdbbdbsbz");
اگر به خصوصیات عبارات منظم نیازی ندارید، راهی جایگزین به نام myArray وجود دارد که یک آرایه ایجاد جدید ایجاد میکند:
const myArray = /d(b+)d/g.exec("cdbbdbsbz");
// similar to 'cdbbdbsbz'.match(/d(b+)d/g); however,
// 'cdbbdbsbz'.match(/d(b+)d/g) outputs [ "dbbd" ]
// while /d(b+)d/g.exec('cdbbdbsbz') outputs [ 'dbbd', 'bb', index: 1, input: 'cdbbdbsbz' ]
اگر قصد دارید الگو را از روی رشته بسازید، روش دیگری هم وجود دارد که عبارت است از:
const myRe = new RegExp("d(b+)d", "g");
const myArray = myRe.exec("cdbbdbsbz");
با استفاده از این Dom در جاوا اسکریپت، اگر الگو پیدا شود آرایهای با ویژگیهایی که در جدول زیر آمده است نمایش داده میشود:
شی | شاخص | توضیحات | مثال |
myArray | رشته منطبق و همه رشته های فرعی را ذخیره میکند. | [‘dbbd’, ‘bb’, index: 1, input: ‘cdbbdbsbz’] | |
index | شاخص مبتنی بر 0 مطابقت در رشته ورودی. | 1 | |
input | رشته اصلی. | ‘cdbbdbsbz’ | |
[0] | آخرین کاراکترهای منطبق. | ‘dbbd’ | |
myRe | lastIndex | شاخصی که عبارت بعدی را با آن شروع کنید. (این ویژگی فقط در صورتی تنظیم میشود که عبارت منظم از گزینه g استفاده کند که در جستجوی پیشرفته با پرچمها توضیح داده شده است.) | 5 |
source | متن الگو. در زمانی که عبارت منظم ایجاد میشود، بهروز می شود، اجرا نخواهد شد. | ‘d(b+)d’ |
همانطور که در شکل دوم این مثال نشان داده شده است، میتوانید از یک عبارت منظم ایجاد شده با شیء اولیه بدون اختصاص دادن آن به یک متغیر استفاده کنید. با این حال، اگر این کار را انجام دهید، هر اتفاقی میتواند عبارت منظم جدیدی ایجاد کند. به همین دلیل، اگر از این فرم بدون اختصاص دادن آن به یک متغیر استفاده کنید، نمیتوانید به ویژگیهای آن عبارت منظم دسترسی داشته باشید. بهعنوان مثال، فرض کنید این اسکریپت را دارید:
const myRe = /d(b+)d/g;
const myArray = myRe.exec("cdbbdbsbz");
console.log(`The value of lastIndex is ${myRe.lastIndex}`);
// "The value of lastIndex is 5"
توجه کنید که با هر بار استفاده از این شکل از ساختار بدون انتساب به متغیر، Regular expressions یک شیء جدید میسازد. به همین علت اگر متغیری را به الگو اختصاص ندهیم، بعداً امکان دسترسی به آن شیء وجود دارد. برای مثال:
const myArray = /d(b+)d/g.exec("cdbbdbsbz");
console.log(`The value of lastIndex is ${/d(b+)d/g.lastIndex}`);
// "The value of lastIndex is 0"
حالا اگر به اسکریپت دقت کنیم، میبینیم که خروجی با مثال قبلی فرق دارد.
دلیل این تفاوت در خروجی دو دستور بالا، این است که با دو شیء رگولار اکسپرشن متفاوت سروکار داریم. پس طبیعتاً ویژگیهایی مانند lastIndex هم برای هرکدام مقدار متفاوتی خواهد داشت. نتیجهی این موضوع این است که اگر نیاز به دسترسی به ویژگیهای یک رگولار اکسپرشن ساخته شده با سازندهی شیء دارید، حتما آن را اول به یک متغیر اختصاص دهید.
پیشنهاد مطالعه: آموزش تابع Date در جاوا اسکریپت به زبان ساده + مثال و نمونه کد
جستجوی پیشرفته با پرچم یا فلگ
عبارات منظم، پرچمهای اختیاری دارند که عملکردهای متفاوتی مانند جستجوی سراسری و جستجوی بدون حساسیت به حروف بزرگ را فراهم میکند. از این پرچمها میتوان بهصورت جداگانه یا ترتیبی استفاده کرد و بهعنوان بخشی از عبارت منظم در آموزش عبارات منظم در جاوا اسکریپت استفاده کرد.
معرفی مهمترین Flag در جاوا اسکریپت:
پرچم | توضیحات | خاصیت مرتبط |
d | ایجاد شاخصهایی برای مطابقتهای زیر رشتهای. | hasIndices |
g | جستجوی جهانی. | global |
i | جستجوی بدون حروف بزرگ. | ignoreCase |
m | به ^ و $ اجازه میدهد تا با کاراکترهای خط جدید مطابقت داشته باشند. | multiline |
s | برای مطابقت با کاراکترهای جدید . اجازه میدهد. | dotAll |
u | “یونیکد”؛ یک الگو را به عنوان دنبالهای از نقاط کد یونیکد در نظر میگیرد. | unicode |
v | ارتقاء به حالت u با ویژگیهای بیشتر یونیکد. | unicodeSets |
y | جستجوی «چسبنده» را با توجه به شروع موقعیت فعلی در رشته هدف که مطابقت دارد، انجام میدهد. | sticky |
برای اضافه کردن پرچم به الگو، از این دو حالت میتوانیم استفاده کنیم:
const re = /pattern/flags;
یا
const re = new RegExp("pattern", "flags");
پرچمها جزء جداییناپذیر از الگو هستند. به همین علت پس از ساخت الگو، پرچمها را به آن اضافه یا از آن کم کرد.
بهعنوان مثال، عبارت re = /\w+\s/g یک الگوی رگولار اکسپرشن میسازد که به دنبال یک یا چند کاراکتر به دنبالِ یک فاصله میگردد. پرچم g در این عبارت باعث میشود الگو در کل متن به دنبال این ترکیب بگردد، نه اینکه فقط به اولین مورد اکتفا کند.
const re = /\w+\s/g;
const str = "fee fi fo fum";
const myArray = str.match(re);
console.log(myArray);
// ["fee ", "fi ", "fo "]
خط زیر را هم میتوانیم به جای خط قبلی بنویسیم و به نتیجهی مشابه برسیم:
const re = /\w+\s/g;
همراه با:
const re = new RegExp("\\w+\\s", "g");
در این مثال پرچم m یک رشته ورودی چند خطی را بهعنوان چندین خط تعیین میکند. اگر از پرچم فوق استفاده شود کاراکترهای ^ (آغاز) و $ (پایان) به جای اینکه به ابتدای کل متن و انتهای آن اشاره کنند، به ابتدای هر خط و انتهای هر خط اشاره میکنند.
استفاده از پرچم جستجوی سراسری با exec
متد ()RegExp.prototype.exec با پرچم g هر بار یک تطابق و موقعیت آن را به صورت تکراری بر میگرداند.
const str = "fee fi fo fum";
const re = /\w+\s/g;
console.log(re.exec(str)); // ["fee ", index: 0, input: "fee fi fo fum"]
console.log(re.exec(str)); // ["fi ", index: 4, input: "fee fi fo fum"]
console.log(re.exec(str)); // ["fo ", index: 7, input: "fee fi fo fum"]
console.log(re.exec(str)); // null
برخلاف این روش، متد match() شیء نمونهی String همهی تطابقها را یکجا برمیگرداند، اما موقعیت آنها را نشان نمیدهد.
console.log(str.match(re)); // ["fee ", "fi ", "fo "]
استفاده از عبارات منظم یونیکد
پرچم u برای ایجاد عبارات منظم «یونیکد» استفاده میشود. یعنی عبارات منظمی که از تطبیق با متن یونیکد پشتیبانی میکنند. یکی از ویژگیهای مهمی که در حالت یونیکد فعال میشود، فرار از ویژگی Unicode است. بهعنوان مثال، عبارت منظم زیر ممکن است برای مطابقت با یک کلمه یونیکد دلخواه استفاده شود:
/\p{L}*/u;
عبارات منظم یونیکد نیز رفتار اجرایی متفاوتی دارند.
سخن پایانی
زبان Javascript یکی از پرطرفدارترین زبانهای برنامه نویسی در دنیا است. در این آموزش عبارات منظم در جاوا اسکریپت را بهطور شرح دادیم و برای هر کدام مثالهای عملی زیادی را توضیح دادیم. چنانچه سوالی در این زمینه دارید، میتوانید در قسمت نظرات بنویسید تا به آنها پارسخ دهیم.
آموزش جاوا اسکریپت با مکتب خونه
جاوا اسکریپت به علت پرکاربرد بودن آن تقاضای زیادی در بازار کار دارد. به همین علت آموزش جاوا اسکریپت برای برنامه نویسان اهمیت فراوانی دارد. مکتب خونه آموزش عبارات منظم در جاوا اسکریپت را توسط برترین مدرسین برگزار میکند که جدیدتر متد این زبان یعنی بک تیک در جاوا اسکریپت را نیز آموزش داده است.
شما میتوانید با شرکت در دورههای آموزش جاوا اسکریپت، آموزش برنامه نویسی و آموزش طراحی سایت جایگاه ویژهای در بازارکار برنامه نویسی بدست آورید و موقعیت شغلی خود را ارتقا دهید.
رفرنس: developer.mozilla
نوشته آموزش عبارات منظم در جاوا اسکریپت اولین بار در مکتوب. پدیدار شد.
منبع