70- آموزش جاوااسکریپت | قسمت اول -آشنایی با عبارات باقاعده (Regular Expressions) و متدهای ارزیابی آنها
در این آموزش با مفهوم عبارات باقاعده (Regex) آشنا شده و ۵ متد اصلی جاوااسکریپت برای کار با آنها یعنی exec، test، match، search و replace را به همراه فلگهای مهم بررسی میکنیم.
آشنایی با Regular Expressions در جاوااسکریپت و توابع ارزیابی الگو (بخش اول)
عبارات باقاعده یا Regular Expressions (Regex) الگوهایی برای توصیف، جستوجو، تطبیق (Pattern Matching) و استخراج داده از متنها هستند. این ابزار مختص جاوااسکریپت نیست و تقریباً در تمامی زبانهای برنامهنویسی وجود دارد. از متداولترین کاربردهای Regex میتوان به اعتبارسنجی فرمها (ایمیل، شماره تماس، کد ملی و...) اشاره کرد.
موضوع Regex شامل متاکاراکترها و نمادهای متعددی است و میتواند بسیار پیچیده شود؛ اما در این بخش بهجای درگیر شدن مستقیم با سیمبلهای پیچیده، ساختار تعریف الگو و توابع ارزیابی Regex در جاوااسکریپت را قدمبهقدم بررسی میکنیم.
۱. ساختار تعریف Regex و خاصیت source
سادهترین روش تعریف Regex در جاوااسکریپت، استفاده از فرمت Literal (قرار دادن الگو میان دو اسلش /.../) است:
let re;
re = /hello/;
در این مثال، هر کاراکتر یک Literal Character است؛ یعنی موتور جستوجو دقیقاً به دنبال کلمه hello (حرف به حرف: h، سپس e، سپس l، سپس l، سپس o) میگردد.
تفاوت چاپ الگو با re و re.source
console.log(re); // خروجی: /hello/
console.log(re.source); // خروجی: hello
- چاپ خود متغیر
re، الگو را همراه با اسلشهای ابتدا و انتها نمایش میدهد. - ویژگی
re.sourceاسلشها را نادیده گرفته و فقط رشتهٔ خالص داخل الگو را برمیگرداند.
۲. توابع ارزیابی الگو (توابع شیء RegExp)
دو تابع اول روی خودِ نمونهٔ Regex فراخوانی میشوند و رشتهٔ مورد نظر را به عنوان آرگومان ورودی دریافت میکنند.
متد اول: exec()
متد exec() رشته ورودی را از چپ به راست بررسی میکند:
- در صورت پیدا شدن مطابقت، یک آرایه شامل اطلاعات کامل برمیگرداند.
- در صورت عدم مطابقت، مقدار
nullبرمیگرداند.
let re = /hello/;
const result = re.exec('hello world');
console.log(result);
خروجی در کنسول:
["hello", index: 0, input: "hello world"]
این آرایه ۳ بخش اصلی دارد:
result[0]: رشتهای که با الگو مطابقت پیدا کرده است (hello).result.index: ایندکس شروع مطابقت در رشته ورودی (در اینجا کاراکتر اول برابر با ایندکس0).result.input: کل رشتهٔ اولیهای که به تابع پاس داده شده است (hello world).
بررسی رفتار exec() با مثالهای مختلف:
-
تغییر موقعیت کلمه در رشته:
const result = re.exec('Brad hello world'); console.log(result.index); // 5 (چون کلمه hello از ایندکس ۵ شروع میشود) -
عدم وجود تطابق کامل:
const result = re.exec('hi world'); console.log(result); // null (چون کلمه hello وجود ندارد) -
دسترسی به بخشهای مختلف خروجی:
console.log(result[0]); // hello console.log(result.index); // 0 (یا هر ایندکسی که پیدا شده) console.log(result.input); // hello world
متد دوم: test()
اگر تنها هدف ما این باشد که بدانیم آیا الگو در متن وجود دارد یا خیر، متد test() بهترین گزینه است. این متد خروجی بولین (true یا false) برمیگرداند.
let re = /hello/;
const result = re.test('Hello');
console.log(result); // false
چرا مقدار false شد؟
عبارات باقاعده بهصورت پیشفرض Case-Sensitive (حساس به حروف کوچک و بزرگ) هستند. در الگوی ما حرف h کوچک است، اما در ورودی H بزرگ وارد شده است.
۳. معرفی فلگها (Flags) در Regex
فلگها بعد از اسلش دوم قرار میگیرند و رفتار ارزیابی الگو را تغییر میدهند:
۱. فلگ i (Case-Insensitive)
این فلگ حساسیت به بزرگ و کوچک بودن حروف را غیرفعال میکند:
let re = /hello/i;
console.log(re.test('Hello')); // true
۲. فلگ g (Global Search)
بهصورت پیشفرض، جستوجو با پیدا کردن اولین تطابق متوقف میشود. فلگ g باعث میشود کل متن برای یافتن تمام موارد جستوجو شود.
۴. توابع رشتهای برای ارزیابی Regex (String Methods)
برخلاف exec و test که متدهای شیء RegExp هستند، توابع زیر روی خود شیء رشته (String) صدا زده میشوند و الگوی Regex را به عنوان ورودی دریافت میکنند.
متد سوم: match()
رفتار این متد شباهت زیادی به exec() دارد، با این تفاوت که برعکس فراخوانی میشود (str.match(re)):
const re = /hello/i;
const str = 'Hello There';
const result = str.match(re);
console.log(result);
// خروجی: ["Hello", index: 0, input: "Hello There"]
نکته: چون از فلگ
iاستفاده شده، مقدار خروجی در ایندکس صفر برابر با کاراکترهای منطبقشده از رشته (Hello) خواهد بود. در صورت عدم تطابق نیز مقدارnullبرگشت داده میشود.
متد چهارم: search()
این متد عملکردی شبیه به indexOf دارد؛ ایندکسِ اولین کاراکترِ منطبقشده را برمیگرداند و در صورت پیدا نشدن، مقدار -1 میدهد:
const re = /hello/i;
const str = 'Brad hello there';
const result = str.search(re);
console.log(result); // 5 (محل شروع hello در رشته)
اگر کلمه پیدا نشود:
const str = 'Brad hi there';
console.log(str.search(re)); // -1
متد پنجم: replace()
این متد الگوی تطبیقیافته را در رشته پیدا کرده و آن را با یک مقدار جدید جایگزین میکند و رشتهٔ جدید را برمیگرداند:
const re = /hello/i;
const str = 'Hello There';
const newStr = str.replace(re, 'Hi');
console.log(newStr); // "Hi There"
جدول مقایسه توابع ارزیابی Regex
| تابع | متعلق به | آرگومان ورودی | مقدار بازگشتی |
|---|---|---|---|
exec() | RegExp | رشته (String) | آرایه اطلاعات مطابقت یا null |
test() | RegExp | رشته (String) | true یا false |
match() | String | الگو (RegExp) | آرایه اطلاعات مطابقت یا null |
search() | String | الگو (RegExp) | ایندکس اولین تطابق یا -1 |
replace() | String | الگو + مقدار جایگزین | رشته جدید با مقدار جایگزینشده |
گام بعدی
در بخشهای بعدی، به سراغ کاراکترهای ویژه و متا کاراکترهای ساخت الگو (مانند ^، $، .، *، کاراکترهای بازه و کمیتسنجها) میرویم و در انتهای این بخشها یک پروژه کامل اعتبارسنجی فرم (Form Validation) پیادهسازی خواهیم کرد.