یک عبارت باقاعده (یا Regex) دنبالهای از نویسههاست که میتوانیم از آن برای هدف گرفتن و دستکاری عناصر مشخصی در رشتهها استفاده کنیم. بنابراین میتوانیم:
این مفهوم بر استفاده از عبارات باقاعده در JavaScript تمرکز دارد. اگر میخواهید بدانید چطور عبارات باقاعده بنویسید، Eloquent JavaScript میتواند منبع خوبی باشد.
💡 گونهی regex در JavaScript بخشی از استاندارد ECMA-262 برای این زبان است. یعنی لازم نیست نگران سازگاری مخصوص هر مرورگر باشید.
در JavaScript، عبارات باقاعده بیشتر به شکل /pattern/modifiers نوشته میشوند که در آن «pattern» الگوی اصلی regex است و «modifiers» رشتهای از نویسههاست که میتوانیم برای نشان دادن گزینههای ویژه (مثل ابرقدرتها) به آن اضافه کنیم.
با این حال، دو راه برای ساختن یک عبارت باقاعده داریم:
const regex = /[a-z]/;
const regex = new RegExp('[a-z]');
در هر دو حالت، JavaScript از regex یک شیء میسازد. توصیه میشود بهطور پیشفرض از الگوهای تغییرناپذیر همراه با لیترال استفاده کنید.
از سازندهی RegExp میتوان در مواردی استفاده کرد که regex تغییر میکند یا هنوز آن را نمیدانیم (مثل یک ورودی).
عبارات باقاعده ابرقدرتهای اختیاریای به نام flags دارند که امکانات بیشتری فراهم میکنند. این پرچمها را میتوان جداگانه یا با هم و به هر ترتیبی به کار برد و بخشی از خود عبارت باقاعده به شمار میآیند.
برخی از پرکاربردترینها عبارتاند از:
/g - جستوجوی سراسری/i - بیتوجه به بزرگی و کوچکی حروف/m - جستوجوی چندخطییک مثال ساده:
const re = /home/gi;
const str = 'Home, sweet home.';
str.match(re);
// => ["Home", "home"]
نویسهی g به ما اجازه میدهد همهی تطبیقهای ممکن در یک رشته را پیدا کنیم. بدون این ویژگی، JavaScript فقط اولین تطبیق Home را استخراج میکرد.
پرچم بیتوجه به بزرگی و کوچکی حروف /i ما را در یافتن یک الگو منعطف میکند. به این ترتیب مهم نیست آنچه میگردیم با حروف UPPERCASE نوشته شده باشد یا lowercase.
وقتی از سازندهی RegExp استفاده میکنید، نحوهی نگارش افزودن پرچمها متفاوت است. در این حالت، فقط کافی است پرچمها را به عنوان آرگومان دوم بدهید.
وقتی عبارات باقاعده با توابع توکار کنونی JavaScript ترکیب میشوند، روشهای قدرتمندی برای دستکاری رشتهها و گرفتن داده از آنها در اختیار داریم.
متد test() راه عالیای برای جستوجو و فهمیدن این است که آیا مقدار هدف در رشتهی دادهشده وجود دارد یا نه. به این ترتیب، یک «مقدار منطقی» برمیگرداند: true یا false.
متد match() تطبیق عبارت باقاعده را از یک رشتهی دادهشده استخراج میکند و آرایهای همراه با اطلاعات و تطبیقها برمیگرداند.
کدام را کجا به کار ببریم؟ وقتی راهی سریع برای بررسی وجود مقداری در یک رشته میخواهید از test() استفاده کنید و اگر به خود آن مقدار نیاز دارید یا اطلاعات بیشتری دربارهی تطبیق میخواهید از match() استفاده کنید.
متد test() جستوجویی برای یافتن تطبیق میان یک عبارت باقاعده و یک رشتهی مشخص انجام میدهد. مقدار «درست» یا «غلط» را برمیگرداند.
const str = 'It is difficult to test if you have a virus';
const result = /virus$/.test(str);
console.log(result);
// => true
خب، اما اگر بخواهیم مقادیر واقعی جستوجوی عبارت باقاعده را به دست آوریم چه؟
متد match() به جای برگرداندن تنها یک مقدار منطقی، آرایهی مفیدی به ما میدهد که محتویاتش به وجود یا نبود تطبیقهای یافتهشده بستگی دارد.
به این ترتیب میتوانیم هم در هر رشتهای جستوجو کنیم و هم اطلاعاتی را استخراج کنیم. مثلاً:
const funnyQuote =
'If you see someone crying, ask if it is because of their haircut.';
const regex1 = /someone/;
const regex2 = /happy/;
funnyQuote.match(regex1);
// => ["someone", index: 3, input: "If you see someone crying, ask if it is because of their haircut.", groups: undefined]
funnyQuote.match(regex2);
// => null
وقتی پرچم جستوجوی سراسری /g حاضر باشد، متد به جای گرفتن تنها تطبیق همراه با اطلاعات مفیدی مثل اندیس یا ورودی، همهی رخدادهای موجود در آرایه را برمیگرداند:
const funnyQuote =
'If you see someone crying, ask if it is because of their haircut.';
const regex3 = /if/gi;
funnyQuote.match(regex3);
// => ["If", "if"];
متد replace() در JavaScript به ما اجازه میدهد مقداری را در یک رشتهی دادهشده جستوجو کنیم و آن را با مقدار جدیدی جایگزین کنیم.
string.replace(searchValue, newValue);
الگوی جستوجوی جایگزینی میتواند یک رشتهی تنها یا یک عبارت باقاعده باشد.
let string = 'I like dogs!';
let result = string.replace('dogs', 'cats');
let string = 'I would love to travel to Japan';
let result = string.replace(/Japan/g, 'Hawaii');
علاوه بر این، میتوانیم تابعی را روی جایگاه جایگزینی اعمال کنیم تا تغییرات بیشتری روی هر مقدار بدهیم.
let text = 'Say hello to the chatbot.';
let result = text.replace(/chatbot|hello/gi, function (word) {
return word.toUpperCase();
});
// => "Say HELLO to the CHATBOT"
💡 در نهایت، ترکیب عبارات باقاعده و متد
replace()راهی پویاتر برای جایگزین کردن عناصر است. استفاده از یک رشتهی تنها ممکن است محدود باشد.
متد split() در JavaScript روش متفاوتی برای استفاده از رشتهها و دستکاری آنها با عبارات باقاعده است.
به این ترتیب، از regex استفاده میکنیم تا رشتهای دادهشده را با تشخیص یک الگو تقسیم کنیم، مثلاً str.split(/[,.\s]/). این الگو به عنوان separator به کار میرود.
const str = 'hello,user.how are.you';
const result = str.split(/[,.\s]/);
console.log(result);
// => ['hello', 'user', 'how', 'are', 'you']
از نظر کارایی، هر دو یک شیء RegExp میسازند. تفاوت اصلی در این است که regex هر چند وقت یک بار کامپایل میشود:
Regular Expression Literal: یک بار، هنگام تجزیه و کامپایل اولیهی کدRegExp(): هر بار که شیء جدیدی ساخته میشود.نوشتن با نحوهی نگارش لیترال ممکن است گزینهی بهتری باشد، نه فقط به خاطر کارایی، بلکه به خاطر سادگی و خوانایی. برای جزئیات بیشتر، این بحث Stackoverflow را ببینید.
RegExp() استفاده میکنید، باید کوتیشنها را escape کنید و بکاسلشها را دو بار escape کنید. این کار عبارات باقاعدهای را که بهخودیخود سخت خوانده و فهمیده میشوند، سختتر هم میکند.