آموزشی مقدماتی بر REGEX در جاوااسکریپت

گردآوری و تالیف : ارسطو عباسی
تاریخ انتشار : 17 تیر 1397
دسته بندی ها : آموزشی

هر کسی که با جاوااسکریپت کار کند مطمئنا در مرحله‌ای از کارهای‌ش به رشته‌ها نیاز خواهد داشت. برخی اوقات تنها نیاز دارید که یک رشته را در یک متغیر دیگر قرار دهید و آن را در جایی استفاده کنید. در برخی دیگر از حالات نیاز است که آن را بررسی کنید و دنبال زیررشته‌هایی در آن باشید. 

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

تصور کنید که نیاز است تمام رشته‌های «Apples» در یک متن را به «apples» تغییر دهید. برای چنین کاری تنها نیاز است که به سادگی از خط کد زیر استفاده کنید:

theMainString.replace("Apples", "apples")

حال تصور کنید که قصد جایگزین کردن appLes با apples را داریم. در این حالت appLES نیز باید به apples تبدیل شود. در این صورت باید تمام نوع‌های مختلف Apple را به apple تغییر دهیم. قرار دادن یک رشته ساده به عنوان آرگومان، در این حالت دیگر کاربردی و کارایی نخواهد داشت.

اینجا جائیست که عبارات با قاعده یا Regular Expression وارد کار می‌شود - شما می‌توانید از پرچم i که نشان‌دهنده غیرحساس بودن به بزرگی و کوچکی حروف است برای مثال بالا استفاده کنید. با قرار دادن این پرچم در جای درست، دیگری اهمیتی نخواهد داشت که رشته اصلی Apples، ApPlEs یا... باشد. تمام نمونه‌های موجود به apples تغییر پیدا خواهند کرد.

درست مانند پرچم غیرحساس به بزرگی و کوچکی، عبارات باقاعده ویژگی‌های بسیار دیگری را نیز ارائه می‌کند که سعی می‌کنیم در این مطلب چند مورد از آن‌ها را بیان کنیم.

استفاده از عبارات باقاعده در جاوااسکریپت

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

به سراغ مثال قبلی بازگردیم، در اینجا می‌توانید استفاده درست از متد replace() را در یک ساختار همراه با عبارات باقاعده مشاهده کنید:

"I ate Apples".replace("Apples", "apples");
// I ate apples
 
"I ate Apples".replace(/Apples/i, "apples");
// I ate apples
 
"I ate aPPles".replace("Apples", "apples");
// I ate aPPles
 
"I ate aPPles".replace(/Apples/i, "apples");
// I ate apples

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

بک‌اسلش در عبارات باقاعده

شما می‌توانید کاراکترهای عادی را با اضافه کردن بک‌اسلش به قبل از آن‌ها به کاراکترهای منحصر به فردی تبدیل کنید. به صورت مشابه، می‌توانید چنین کاری را با کاراکترهای منحصر به فرد نیز انجام دهید. 

برای مثال d یک کاراکتر منحصر به فرد نیست. با این حال \d برای تطبیق دادن یک کاراکتر عددی در یک رشته کاربرد دارد. به صورت مشابه D هم یک کاراکتر منحصر به فرد نیست، اما \D برای تطبیق دادن کاراکترهای غیر عددی در یک رشته استفاده می‌شود.

کاراکترهای عددی شامل ۱،۲،۳،۴،۵،۶،۷،۸ و ۹ می‌شود. وقتی از \d در داخل یک عبارت باقاعده استفاده می‌کنید، اعداد را با حروف مناسب تطبیق می‌دهد. اما زمانی که از \D استفاده می‌کنید کاراکترهای غیرعددی تطبیق می‌یابند. 

برای اینکه این مفهوم ساده‌تر شود، به مثال زیر نگاه کنید:

"L8".replace(/\d/i, "E");
// LE
 
"L8".replace(/\D/i, "E");
// E8
 
"LLLLL8".replace(/\D/i, "E");
// ELLLL8

دقت کنید که در مثال سوم تنها کاراکتر ابتدایی رشته تغییر پیدا کرد. می‌توانید از پرچم‌ها برای جایگزینی تمام موارد منطبق استفاده کنید. در رابطه با این پرچم‌ها بیشتر آشنا خواهیم شد.

درست مانند \d و \D تعداد کاراکترهای منحصر به فرد دیگری نیز وجود دارد.

۱- می‌توانید از \w برای پیدا کردن تمام کاراکترهای کلمه‌ای در یک رشته استفاده کنید. منظور از کاراکترهای کلمه‌ای حروف A-Z, a-z,0-9 و ـ است. بنابراین \w تمام اعداد، حروف الفبایی بزرگ و کوچک و ـ (آندرسکور) را پیدا می‌کند. 

۲- می‌توانید از \W برای پیدا کردن تمام کاراکترهای غیر عددی در یک رشته استفاده کرد. کاراکترهایی مانند #,$,% و... .

۳- می‌توانید از \s برای پیدا کردن یک کاراکتر فضای سفید استفاده کنید، این کاراکتر می‌توانید شامل space، tab و... باشد. به صورت مشابه می‌توانید از \S برای پیدا کردن تمام کاراکترها در کنار فضای سفید استفاده کنید. 

۴- همچنین می‌توانید با استفاده از \f, \n , \r, \t و \v برای پیدا کردن فضاهای خالی منحصر به فردتری اقدام نمایید.

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

"A lot of pineapple images were posted on the app".

در این حالت ما قصد داریم که کلمه app را با board جایگزین کنیم. با این حال، استفاده از یک عبارت باقاعده ساده، کلمه apple را به boardle تبدیل می‌کند و در نهایت جمله تبدیل به حالت زیر می‌شود:

"A lot of pineboardle images were posted on the app".

در چنین حالتی باید از یک کاراکتر منحصر به فرد دیگر به نام \b استفاده شود. این مورد برای بررسی مرزهای موجود در کلمات استفاده می‌شود. مرز برای کلمات با استفاده از کاراکترهای غیر-کلمه‌ای مانند $,#,% و... ایجاد می‌شود. -مراقب کاراکترهای لهجه‌دار مانند ü نیز باشید-.

"A lot of pineapple images were posted on the app".replace(/app/, "board");
// A lot of pineboardle images were posted on the app
 
"A lot of pineapple images were posted on the app".replace(/\bapp/, "board");
// A lot of pineapple images were posted on the board

به صورت مشابه شما می‌توانید از \B برای پیدا کردن مرزهای غیر-کلمه‌ای نیز استفاده کنید. برای مثال می‌توانید app در کلمه pineapple را تغییر دهید.

پیدا کردن یک الگو n دفعه

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

می‌توانید از * برای پیدا کردن عبارات قبلی استفاده کنید. برای مثال /Ap*/ کاراکترهای A, Ap, App و... را مورد بررسی قرار می‌دهد.

در یک حالت معنادار دیگر می‌توانید از + برای مثال قبلی استفاده کنید. اما در این حالت ابتدایی‌ترین قدم در نظر گرفته نمی‌شود. بنابراین دستور /Ap+/ کاراکترهای Ap, App, Appp و... را بررسی می‌کند. 

برخی اوقات تنها می‌خواهید یک عدد منحصر به فرد از تکرار را در یک الگوی متنی مورد بررسی قرار دهید. در چنین حالت‌هایی باید از کاراکتر ترتیبی {n} استفاده کنید. منظور از n یک عدد است. برای مثال /Ap{2}/ کلمه App را به جای Ap مورد نظر قرار می‌گیرد.

می‌توانید از {n,} برای حداقل n بار تکرار در یک عبارت استفاده کنید. این بدان معناست که /Ap{2,}/ کلمه App را مورد بررسی قرار می‌دهد نه Ap را. همچنین این دستور می‌توانید تمام pهای داخل Apppp را پیدا کرده و آن را با رشته جایگزین شما، تغییر دهد.

همچنین می‌توانید از {n,m} برای بررسی کردن حداکثر و حداقل تکرار در یک عبارت استفاده کنید. برای مثال /Ap{2,4}/ کلمات App, Appp و Apppp را بررسی می‌کند.

"Apppppples".replace(/Ap*/, "App");
// Apples
 
"Ales".replace(/Ap*/, "App");
// Apples
 
"Appppples".replace(/Ap{2}/, "Add");
// Addppples
 
"Appppples".replace(/Ap{2,}/, "Add");
// Addles
 
"Appppples".replace(/Ap{2,4}/, "Add");
// Addples

استفاده از پارانتزها برای یادآوری تطبیق‌ها

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

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

"I like Apple".replace(/(\w{5,})/, '$1s');
// I like Apples
 
"I like Banana".replace(/(\w{5,})/, '$1s');
// I like Bananas

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

در داخل رشته جایگزینی اولین مورد تطبیقی توسط $1 و دومین مورد توسط $2 شناسایی می‌شود. این حالت به همین صورت ادامه خواهد داشت. در این جا می‌توانید یک مثال دیگر از این حالت را برای استفاده درست و واضح‌تر از پرانتزها را مشاهده کنید:

"I am looking for John and Jason".replace(/(\w+)\sand\s(\w+)/, '$2 and $1');
// I am looking for Jason and John

استفاده از پرچم‌ها در عبارات با قاعده

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

در اینجا می‌توانید ۴ پرچم که به معمولا زیاد استفاده می‌شود را مشاهده کنید:

  • g: این پرچم به صورت همگانی جستجو را انجام می‌دهد. حالتی که اگر بدون آن انجام شود، بعد از پیدا کردن اولین مورد تطبیقی جستجو متوقف می‌شود.
  • i: این پرچم برای جستجو در حالتی که بزرگی و کوچکی کلمه مهم نباشد استفاده می‌شود. برای مثال Apple, aPPle, aPPLE و... همگی یکی خواهند بود.
  • m: این پرچم برای جستجوی چند-خطی استفاده می‌شود.
  • y: از این پرچم برای پیدا کردن از طریق lastIndex استفاده می‌شود.

چند مثال از عبارات باقاعده همراه با پرچم‌ها را می‌توانید در زیر مشاهده کنید:

"I ate apples, you ate apples".replace(/apples/, "mangoes");
// "I ate mangoes, you ate apples"
 
"I ate apples, you ate apples".replace(/apples/g, "mangoes");
// "I ate mangoes, you ate mangoes"
 
"I ate apples, you ate APPLES".replace(/apples/, "mangoes");
// "I ate mangoes, you ate APPLES"
 
"I ate apples, you ate APPLES".replace(/apples/gi, "mangoes");
// "I ate mangoes, you ate mangoes"
 
 
var stickyRegex = /apples/y;
stickyRegex.lastIndex = 3;
"I ate apples, you ate apples".replace(stickyRegex, "mangoes");
// "I ate apples, you ate apples"
 
var stickyRegex = /apples/y;
stickyRegex.lastIndex = 6;
"I ate apples, you ate apples".replace(stickyRegex, "mangoes");
// "I ate mangoes, you ate apples"
 
var stickyRegex = /apples/y;
stickyRegex.lastIndex = 8;
"I ate apples, you ate apples".replace(stickyRegex, "mangoes");
// "I ate apples, you ate apples"

سخن پایانی + دوره آموزشی «آموزش کامل عبارات باقاعده - Regular Expressions»

هدف این مطلب آشنا کردن شما با عبارات باقاعده در جاوااسکریپت و میزان اهمیت آن‌ها بود. ما در ابتدای کار با پایه‌ها شروع کردیم و سپس وارد کاراکترهای منحصر به فرد شدیم. همچننین چندین الگوی تکرار در رشته‌ها را بررسی کردیم. در نهایت با بحث پرچم‌ها در خدمت‌تان بودیم. اگر دوست دارید که به صورت تخصصی‌تر با عبارات باقاعده آشنا شوید پیشنهاد می‌کنم که حتما دوره آموزشی «آموزش کامل عبارات باقاعده - Regular Expressions» را دنبال کنید. 

منبع

مقالات پیشنهادی

تست واحد جاوااسکریپت برای مبتدیان

تست‌های واحد یا Unit Test بخش‌هایی از یک کد را بررسی می‌کند این بررسی کردن برای اطمینان حاصل نمودن شما از اجرای درست کدها صورت می‌گیرد. این مورد در دن...

چرا Async؟ جاوااسکریپت و دنیای واقعی

در واقع، ممکن است که قبلا عبارت «callback hell» را شنیده باشید. این عبارت بی دلیل ساخته نشده بود: کدی که بر پایه callback باشد، به ناچار در جایی ختم م...

۱۲ سوال متداول جاوااسکریپت و جواب‌های‌شان  - بخش سوم

در این مطلب قصد داریم که شما را با ۱۲ سوال مرسوم و متداول که مربوط به جاوااسکریپت است آشنا کنیم. این‌ها سوالاتی هستند که نه فقط افراد عادی بلکه افراد...

۱۲ سوال متداول جاوااسکریپت و جواب‌های‌شان  - بخش دوم

همانطور که می‌دانیم جاوااسکریپت یکی از منعطف‌ترین ابزارها برای طراحی وب است. اما با این وجود سوالات و شُبَهات بسیاری در مورد این ابزار وجود دارد