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

عبارات با قاعده (Regular Expressions)در جاوا اسکرییپت ، بطور کلی به اون قوانین ( یا قاعده ) که ما در هنگام جستجو در یک متن یاهم عملیات جایگزینی متن ،تعریف میکنیم گفته میشه.

بهزاد میرزازاده بهزاد میرزازاده

زمان مطالعه

3 دقیقه

بازدید

332

پرسش و پاسخ

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

ساخت یک عبارت منظم و ازمایش منطبق بودن آنها

برای ساخت یا تعریف عبارت منظم (regular expressions) دو راه داریم

  1. استفاده از شی RegExp
  2. استفاده از فوروارد اسلش(//)

مثال:

let first=new RegExp("abc");
let second=/abc/;

هر دوی این مثال ها یک کار رو انجام میدن فقط ی نکته ای هست:

وقتی شما از شی RegExp استفاده میکنید اگر از n\ استفاده کنید ی خط فاصله ایجاد خواهد کرد چون مقادیر درون شی RegExp به عنوان یک استرینگ معمولی تعریف میشن چون بین دابل یا سینگل کتیشن قرار میگیرن .

اما زمانی که از فوروارد اسلش استفاده میکنید و از شی RegExp استفاده نمیکنید n\ تاثیری نخواهد داشت و مانند یک استرینگ در نظر گرفته میشود مثال های زیر را ببینید:

let first = new RegExp('abc\ndef');

console.log(first); output: /abc def/

let second = /abc\ndef/;

console.log(second); output: /abc\ndef/

یکی از متدهایی که در regular expressions وجود داره متد test هست که بررسی میکنه که ایا کاراکتر هایی که بهش میدید جزئی از عبارت منظم هست یا نه مثال زیر رو ببینید

console.log(/abc/.test("123abcde")); // → true

 console.log(/abc/.test("abxde")); // → false

اولی true شد چون ترتیب بین حروفی که در متد تست قرار گرفته مانند عبارت منظم هست و کاراکتر های قبل و بعدش ربطی به اون 3 کاراکتر متوالی ندارند.

دومی هم false خواهد بود زیرا ترتیب رعایت نشده .

نکته: اگر بین مقادیری که در مثال اول درون متد test داده شد space (فاصله) قرار دهیم خروجی false خواهد شد زیرا همانطور که گفتیم ترتیب بین کاراکتر ها باید رعایت شوند.

 

مجموعه ها و کاراکتر ها در regular expressions

در عبارات های منظم قرار دادن مجموعه ای از کاراکتر های بین square bracket [ ] باعث میشه که هر یک از کاراکتر هایی که بین اون مجموعه هستند قابل دسترسی یعنی طبق مثال اول و دوم از 0 تا 9 هر عددی باشه قابل دسترسیه مثال های زیر رو ببینید

example 1:
 let first=/[0-9]/; console.log(first.test('2020');//true 
 example 2:
 let second = /[0123456789]/; console.log(second.test('2020'));//true 
 example 3: 
let second = /[a-z A-Z]/; console.log(second.test('hello ALI')); //true


نکته : حتما باید از دش یا خط تیره (-) استفاده شود زیرا به معنای رنج (محدوده ای ) از اعداد یا کاراکتر ها خواهد بود.

چندین شورتکات(میانبر) وجود دارد که همانطور که میدونید کار مارو اسان تر میکنند:. (dot) هر کاراکتری بحز خط جدید

مثال:

\d هر عددی البته فعلا فقط اعداد لاتین
\w هر کاراکتری که الفبایی باشه و باهاش کلمه درست میشه البته فعلا فقط کاراکترهای انگلیسی
\s فاصله  یا تب یا خط جدید
\D هر کاراکتری که عدد نباشه
\W هر کارکتری که الفبایی نباشه یعنی شامل کارکترهایی که باهاش کلمه ایجاد میشن نباشه
\S فاصله یا تب یا خط جدید نباشه
. (dot) هر کاراکتری بجز خط جدید

let date = /\d\d-\d\d-\d\d\d\d \d\d:\d\d/;
console.log(date.test('30-03-2020 13:24'));//true
console.log(date.test("30-jan-2003 15:20"));//false

این مثال واقعا گیج کنندست.

برای اطمینان حاصل کردن از اینکه تعداد ارقامی که داده میشه دقیق هست باید بعد از d\ از براکت {} استفاده کنیم برای مثال اگر بخواهیم مقادیری که به متد testداده میشن 2 یا 4 رقم باشند حداقل مقداری که میتوان به متد تست داد 2 رقم مثلا 23 و بیشترینش 4 تا هست مثلا 2341

let dateTime = /\d{1,2}-\d{1,2}-\d{4} \d{1,2}:\d{2}/;
console.log(dateTime.test("22-03-2003 8:45"));//true

این روش واقعا عالیه فرض کنید بخواید 100 رقم داشته باشید با استفاده از مثال بالا باید 100 تا d\ بنویسید اما با این روشی که مثالش رو هم بالاتر گفتیم فقط

\d{1,100}

را مینویسید.

نکته مهم: چنانچه اگر شما به المنت اول که مقدار 22 بهش داده شده یک مقدار عددی دیگه اضافه کنید مثلا بجای 22 بنویسید 2222 یا هر عدد دیگه با هر تعداد رقمی بازهم جواب true خواهد بود همچنین بجای المنت اخر که 45 هست نیز هر عددی با هر رقمی بنویسید بازم جواب true خواهد بود برای حل این مشکل باید از علامت های caret(^) و dollar ($) استفاده کنید علامت ^ در ابتدای پترن قرار میگیره و علامت & در پایان پترن البته داخل // ها باید باشند.

مثال :

123let dateTime = /^\d{1,2}-\d{1,2}-\d{4} \d{1,2}:\d{2}$/;
console.log(dateTime.test("22-30-2003 8:41")); //true
console.log(dateTime.test("444-30-2003 8:41")); //false

تکرار کردن بخشی از الگو(پترن) در عبارات منظم

زمانی که شما از علامت بعلاوه (+) بعد از هر مقدار عبارت منظمی استفاده میکنید به این معنیه که اون المنت ممکنه بیش از یکبار مقدار داده بشه مثال زیر رو ببینید :

let oops = /\d+/;
console.log(oops.test(213123));//true

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

1234let str = /^\d+$/; //-> 1 رقم تا هر تعداد رقم
let str1 = /^\d{1,}$/; //-> 1 رقم تا هر تعداد رقم
console.log(str.test(12312));//true
console.log(str1.test(12312));//true

در واقع در مثال بالا نیازی به استفاده از caret (^) و dollar($) نبود اما پیشنهاد میشه در مواردی مثل مثال پایین یا مثال هایی که بالاتر زدیم قرارش بدید چون این علائم پترن رو محدود میکنن و ورودی هایی که به پترن داده میشن نمیتونن بیش از محدوده ای که شما براشون تعیین کردین کم یا زیاد بشن.

اگر بخواهید یکی از کاراکترها رو اختیاری کنید یعنی بگید اگر بود فلان اتفاق بیفته اگر نبود هیچ اتفاقی نیفته از علامت سوال (?) استفاده میکنید مثال زیر رو ببینید :

let str = /^colou?r$/;
console.log(str.test("color"));//true
console.log(str.test("colour"));//true

در پترن بالا ما اومدیم حرف u رو اختیاری کردیم گفتیم اگ u درخط 2 بود که خروجی بده اونم شده true اگرم u نبود که هیچکاری نکن

و همانطور که تو خط 1 میبینید u به متد test داده نشده و روی خروجی هم تاثیری نذاشته.

 

دسته بندی عبارات Grouping subexpressions

چنانچه اگر بخواهید یک بخش از پترن چندین بار تکرار بشود باید از پرانتز استفاده کنید به مثال زیر توجه کنید

let cartoonCrying = /boo+(hoo+)+/i;
console.log(cartoonCrying.test("Booooohoooohoooohooo")); //ture

در این پترن ما خواستیم که hoo به تعداد نامشخصی تکرار بشه به همین دلیل اونو بین پرانتز گذاشتیم و بعلاوه بغل o که توی پرانتز هست برای تکرار نامشخص o هست و بعلاوه بعد از پرانتز مربوط به تکرار نامشخص hoo هست
flag(پرچم) i هم که بعد forward slash (/) آمده به معنای اینکه که پترن case-insensitive نباشه یعنی به حروف بزرگ و کوچک حساس نباشه

 

متد exec

یه متد دیگه علاوه بر متد test داریم (test رو در بخش اول اموزش بهش اشاره کرده بودم) به نام exec که مخفف execute هست این متد میاد بررسی میکنه که ایا مقداری که بهش میدید با پترن تطابق داره یا نه به عبارت دیگه این مقداری که به عنوان ارگومان بهش پاس میدید جزیی از پترن هست یا نه اگه باشه که اوکیه در غیر اینصورت null برمیگردونه به مثال زیر توجه کنید

let str = 'hello guys my name is mohammadali';
let pattern = /(hello)/;
console.log(pattern.exec(str)); 

همانطور که مشاهده میکنید ما اومدیم وجود یا عدم وجود hello رو بررسی کردیم اگر کد بالا رو در کنسول مشاهده کنید خواهید دید که hello در پترن وجود داره البته چیزی که کنسول نمایش خواهد داد یک ارایه خواهد بود که شامل مقادیری از جمله مقدار داده شده به عنوان ارگومان به متد exec هست که hello هست و ایندکس بعدی بازهم مقدار داده شده به متد exec هست با این تفاوت که اگر مقادیر چند تا باشند با comma (,) از همه جدا شدن وایندکس بعدی index خواهد بود که مقدارش 0 خواهد بود چون کاراکتر h صفرمین مقدار هست اگر بجای hello در متد exec مقدار guys رو میدادیم index شش میشد و input هم مقدار داده شده به عنوان ارگومان رو نشون میده با group هم فک نکنم کاری داشته باشیم

["hello", "hello", index: 0, input: "hello guys my name is mohammadali", groups: undefined]

یک مثال دیگه که امیدوارم با توجه به توضیحات بالا متوجه بشید :

let dateTime = '2020-03-28';
let patt = /^(\d{4})[-./](\d{1,2})[-./](\d{1,2})$/;
console.log(patt.exec("2020/12/02")); 
console.log(patt.exec(dateTime)); 

همانطور که میدونید این [-./] کاراکتر ها جدا کننده تاریخ هستن

مرز کلمه (محدودیت کلمه)Word boundary

یک نوع شورتکات (میانبر)دیگه داریم توی عبارت های منظم که برای محدود کردن کلمات مورد استفاده قرار میگیره توضیحی که میشه برای این شورتکات داد اینه : وقتی برنامه شروع به اجرا میکنه ماژول برنامه جستجو رو انجام میده(پیاده سازی میکنه) و وقتی به b\ میرسه متوجه میشه که این شورتکات یک محدود کننده کلمه هست که در ابتدا استرینگ امده

 

سه حالت مختلف وجود داره که میتوان از word boundary استفاده کرد :

  1. در شروع استرینگ , اگر اولین کاراکتر ,کاراکتر استرینگ باشه (کاراکتر خاص نباشه مثل ! # /)
  2. بین دو کاراکتر باشه که اولیش استرینگ باشه و دومیش استرینگ(کاراکتر خاص) نباشه
  3. در پایان استرینگ باشه , اگر اخرین کاراکتر,کاراکتر استرینگ باشه

مثال زیر رو ببینید:

console.log('Hello, JavaScript'.match(/\bHello\b/ig)); //Hello

در مثال بالا بعد از b\ یک کاراکتر استرینگ هست (H) اخرین کاراکترش هم که (o) هست رشته هست حالا مثال زیر رو ببینید :

console.log('Hello, JavaScript'.match(/\bHell\b/ig)); //null

جواب null شد چون بعد کاراکتر (l) کاراکتر (o) رو داریم و شرط دوم که در بالاتر ذکر کردیم رعایت نشده زیرا بعد از هر کاراکتر استرینگی باید یک کاراکتر غیر استرینگی باشه خب بعد (l) کاراکتر (o) هست که اونم استرینگ هست پس جواب null خواهد بود

فلگ i برای این استفاده میشه که case-sensitive بودن مطرح نباشه یعنی استفاده از کاراکترهای بزرگ و کوچک مجازه

فلگ g برای این استفاده میشه که اگر مقادیر دیگه ایم هم بود که با مقدار متد match تطابق داشت اوناروهم دربر بگیره(نشون بده) اگر از این فلگ استفاده نشه متد match زمانی که به اولین مقدار مطنبق(مچ شده) برسه همون یک مقدار رو برمیگردونه و با بقیه مقادیر منطبق کاری نداره و ازشون رد میشه .

تناوب - Alternation

تناوب عبارات کار بسیار ساده ای هست که در عبارات منظم با pipe (|) نشان داده میشود که به نوعی همان کار or در برنامه نویسی رو انجام میده مثال زیر رو ببینید :

let regexp = /html|php|css|java(script)?/gi;
let str = "First HTML appeared, then CSS, then JavaScript"
alert(str.match(regexp)); // 'HTML', 'CSS', 'JavaScript'

نکته : همیشه بایدحداقل یکی از مقادیر پترن با مقادیر متغییر str مچ باشه در غیر اینصورت خروجی null خواهد بود

ما قبلا با square bracket ها اشنا شدیم که تو مثال رنج(محدوده ای ) از اعداد که توی قسمت اول بود بهتر توضیحش دادیم اگر بخاطر داشته باشید ی هچین مثالی داشتیم

[0123456789]

که میشد از بینشون هر عددی رو انتخاب کرد . از | هم میشه به این صورت استفاده کرد مثال های زیر رو ببینید :

let reg = /gr[ea]y/ig;
let str = 'grey';
console.log(str.match(reg)); //["grey"]

let reg2 = /gr(e|a)y/ig;
let str2 = 'grey';
console.log(str2.match(reg2)); //["grey"]

هر دو مثال درسته و جواب یکی خواهد بود

توجه داشته باشید که حتما مقادیری رو که میخواید بصورت متناوب باشه بهتره  بین پرانتز قرار بدید مثل مثال دوم

این مثال رو ببینید در این مثال از پرانتز در پترن استفاده نشده

let reg2 = /gre|ay/ig;
let str2 = 'grey';
console.log(str2.match(reg2));  //["gre"]

یک مثال پیشرفته تر از مثال های بالا

let patt = /^[01]\d|2[0-3]:[0-5]\d$/g;
let str = '12:00';
console.log(patt.exec(str));

پترن رو کاملا شرح میدم اما نیاز به دقت داره

اولین کاراکتر یعنی

[01]/d

میاد میگه که اگه ساعت 0 یا 1 داشت اولش رقم بعدیش میتونه هرچی دیگه باشه مثل:

00/01/02/03/04/05/06/07/08/09/10/11/12/13/14/15/16/17/18/19

منظور از رقم های بالا ساعت به 00am تا 19pm هست. رقم هایی که مربوط به 0 هستند از 00 تا 09 و رقم هایی که مربوط به 1 هستند از 10 تا 19

خب حالا اگر ساعت 21 بود چی ؟ اومدیم براش | گذاشتیم و گفتیم اگر ساعت بجای 0 یا 1 اولش 2 بود بیا عدد بعدیش رو از 0 تا 3 مجاز قرار بده مثل :

20/21/22/23

نکته :24 مجاز نیست چون 00 هست

بعد از : مربوط به دقیقه هست که اونم مثل همینه نیاز به دقت داره البته اونم میگم :

[0-5]

یعنی اولین رقم دقیقه میتونه هر عددی از 0 تا 5 باشه مثل 0/1/2/3/4/5 رقم بعدیم که مربوط به رقم بعدی دقیقه هست مثلا بیست و دو دقیقه اون دو دقیقه میشه رقم دوم و بیست هم رقم اول مثال عددی

59...01

و در اخر مثلا 00:24 ->دوازده و بیست و چهار دقیقه

چنانچه اگر این مثال رو با توضیح من متوجه نشدید میتونید به توضیح اصلی این مثال به لینک زیر مراجعه کنید من سعی کردم یکم مثال رو بازتر کنم که البته ممکنه گیج کننده شده باشه اما دو سه بار بخونید احتمال درکش زیاده :)

https://javascript.info/regexp-alternation

متد replace

متد replace میتونه در جایگزین کردن بخشی از رشته با بخش دیگه مورد استفاده قرار بگیره مثال زیر رو بینید:

console.log('pap'.replace('p', 'm')); //map

همچنین میشه از replace در عبارات منظم هم استفاده کرد مثال زیر رو ببینید :

console.log('hello padrick'.replace(/[d]/, 't'));  //hello patrick

به این مثال هم توجه کنید :

console.log("Borobudur".replace(/[ou]/g, "a")); //Barabadar

در مثال بالا ما از فلگ g استفاده کردیم که همانطور که میدونید تمامی مقادیری رو که منطبق(مچ) باشه رو در بر میگیره در کلمه Borobudur ما دو تا o داریم و دوتا هم u که هر چهارتای اینارو تبدیل به a کرده چون ما تو پترن گفتیم [ou] میتونیم از pipe هم که در بالاتر توضیح دادیم استفاده کنیم مثال زیر رو ببینید :

console.log("Borobudur".replace(/o|u/g, "a")); //Barabadar

چند مثال کمی پیچیده تر :

console.log("Liskov, Barbara\nMcCarthy, John\nWadler, Philip".replace(/(\w+), (\w+)/g, "$2 $1"));

let s = "the cia and fbi"
console.log(s.replace(/\b(fbi|cia)\b/g,str => str.toUpperCase()));
// → the CIA and FBI

در مثال بالا به عنوان ارگومان دوم به متد replace ی ارو فانکشن(arrow function) دادیم که ی مقدار پارامتر بیشتر نداره و همانطور که میدونید وقتی یک ارو فانکشن یک پارامتر داشته باشه میتونه بدون پرانتز و return هم تعریف بشه در واقع منظور اینه :

(str)=>return str.tuUpperCase();

این str که به عنوان پارامتر به ارو فانکشن داده شده مقادیر پترن (که به عنوان ارگومان اول به replace داده شده هست) رو شامل میشه ساده تر اینکه fbi و cia ریخته شدن توی str

ممکنه گیج شده باشید از خوندن این دو تیکه متن اخر اگر شدید دو س بار بخونیدش متوجه میشید چون توش ارگومان و پارامتر زیاد داشت :)

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

let stock = "1 lemon, 2 cabbages, and 101 eggs"
function minusOne(match, amount, unit) {
      amount = Number(amount) - 1; // Number از تعداد یکی کم کن  دلیل استفاده از 
      // رفع خطاهای احتمالی این مبحث توی بیشتر توی error handling کارایی داره
 if (amount == 1) { // اگر تعداد یکی بود 
      unit = unit.slice(0, unit.length - 1); //از صفرمین مقدار تا یکی مانده به اخری رو شامل شو 
 } else if (amount == 0) { 
     amount = "no"
}
     return amount + " " + unit;
}
console.log(stock.replace(/(\d+) (\w+)/g, minusOne))
//no lemon, 1 cabbage, and 100 eggs

در مثال بالا میشه خط سوم رو حذف کرد اون خط صرفا برای این نوشته شده که اگر تعداد تخم مرغ یا کلم یا لیمو بیشتر از یکی بود یکی از تعدادشون کم میکنه

 

فلگ y

از فلگ y برای جستجو در موقعیت (جایگاه) پترن استفاده میشه قبل اینکه درباره فلگ y مثال بزنم مثال زیر رو ببینید :

let str = 'let varName';

let regexp = /\w+/g;
console.log(regexp.lastIndex); // 0 (ابتدا ی lastIndex=0)

let word1 = regexp.exec(str);
console.log(word1[0]); // let (1st word)
console.log(regexp.lastIndex); // 3 (اخرین پوزیشن مچ شده )

let word2 = regexp.exec(str);
console.log(word2[0]); // varName (2nd word)
console.log(regexp.lastIndex); // 11 (اخرین پوزیشن مچ شده )

let word3 = regexp.exec(str);
console.log(word3); // null (مقدار منطبق دیگه ای وجود نداره)
console.log(regexp.lastIndex); // 0 
//(در اخر جستجو تظنیم مجدد میشه یعنی دوباره ازاولین پوزیشن که  0  هست شروع میشه)

برای جستجو کردن مقادیری که توی متغییر str وجود دارن میتونیم از متد exec استفاده کنیم

نکته : اگر پترن ما فلگ g یا y رو نداشته باشه به پیدا کردن اولین مقدار منطبق(مچ) بسنده میکنه

اگر فلگ g وجود داشته باشه شروع میکنه به جستجو اولین مقدار ذخیره شده در رشته و پوزیشن(موقعیت,محل) اخرین کاراکتر رو ذخیره میکنه توی پراپرتی lastIndex و اگر مقدار دیگه ای باشه که منطبق باشه دوباره میره تا اخرین پوزیشن و دوباره اون رو میریزه توی lastIndex و به همین ترتیب

نکته : وقتی پترن شروع به مچ شدن میکنه پوزیشن پراپرتی lastIndex برابر با 0 هست

بنابراین بعد از هربار فراخوانی متغییر str درون exec که مثالش بالا هست مقادیر منطبق شده پشت سرهم توی کنسول نمایش داده میشن تا برسه به اخرین مقدار منطبق شده و چنانچه مقدار قابل انطباقی وجود نداشته باشه خروجی null خواهد بود.

هر مقدار منطبق مانند یک ارایه با گروه و پراپرتی های اضافه خودش هست , ما میتونیم بجای مثال بالا از حلقه استفاده کنیم مثال زیر رو ببینید :

let str = 'let varName';
let regexp = /\w+/g;
let result;
while (result = regexp.exec(str)) {
  console.log( `Found ${result[0]} at position ${result.index}` );
  // Found let at position 0, then
  // Found varName at position 4
}

در واقع حلقه while در اینجا کار متد matchAll رو میکنه

ما میتونیم پوزیشن متد lastIndex رو به صورت کاستوم (دستی) هم مقدار بدیم مثال زیر رو ببینید :

let str = 'let varName = "value"';
let regexp = /\w+/g; //بدون فلگ g 
//متد lastIndex 
//نادیده گرفته میشه
regexp.lastIndex = 4; //پوزیشن دستی که بهش دادیم 
let word = regexp.exec(str);
console.log(word); // varName

نکته مهم : در واقع یکی از تفاوت های فلگ g با y در این است که فلگ g میتونه از قبل یا بعد از اخرین پوزیشن منطبق شده شروع کنه به ثبت پوزیشن توی پراپرتی lastIndex یعنی اگر شما space (فاصله) رو بهش به عنوان پوزیشن بدید میره قبل یا بعدش رو که کاراکتر رشته ای هست رو میگیره اما فلگ y فقط خوده کاراکتر رو به عنوان پوزیشن میریزه توی lastIndex به مثال بالا و پایین توجه کنید .

let str = 'let varName = "value"';
let regexp = /\w+/y;
regexp.lastIndex = 3;
console.log( regexp.exec(str) ); // null (پوزیشن داده شده در اینجا فاصله است نه کاراکتر)
regexp.lastIndex = 4;
console.log( regexp.exec(str) ); // varName (word at position 4)

همانطور که گفتیم و در مثال بالا دیدید در خط چهارم مثال بالا خروجی null شد چون پوزیشن 3 در متغییر str فاصله (space) بود

تصور کنید ما یک متن طولانی داریم و هیچ مقدار قابل انطباقی درونش نیست و شما با فلگ g درونش سرچ میکنید این سرچ تا پایان متن ادامه خواهد داشت این امر زمان قابل ملاحظه ای را بجای سرچ کردن با y خواهد گرفت

 

در کارهای مانند تحلیل واژگان(lexical analysis) معمولا بسیاری از جستجو ها در نقطه دقیق پوزیشن انجام میگیرد .استفاده از فلگ y کلید پرفرمونس (کارایی,اجرا) خوب است

 

کاراکتر caret (^)

از کاراکتر caret (^)علاوه بر محدود کردن پترن که در قسمت اول اموزشمون گفتیم میتوان به عنوان محدود کننده کاراکتر ها هم استفاده کرد برای مثال میتونیم کاراکتر هایی مثل # % رو محدود کنید مثال زیر رو ببینید :

let str = 'example@#email.com';
console.log(str.replace(/\w+/g, ''));  //@#.

برای درک بهتر از متد repalce استفاده کردم .

 

فلگ m

این فلگ برای مقادیر چند خطی مورد استفاده قرار میگیره , به مثال های زیر توجه کنید :

توجه داشته باشید که برای تعریف مقادیر چند خطی درون یک متغییر در جاوا اسکریپت باید از بک تیک(``) استفاده کنید (محل قرار گرفتنش کنار عدد یک روی کیبرد هست زیر Esc)
let str = `Hello
Hello
Hello
`;
console.log(str.replace(/^Hello$/, 'GoodBye')); //پترن نمیتونه شناخته بشه چون مقدار متغییر 
// چند خطی هست str 
//Hello Hello Hello

 

let str = `Hello
 Hello
 Hello
 `; 
console.log(str.replace(/^Hello$/m, 'GoodBye'));  //پترن رشته رو شناخت 
// GoodBye  Hello Hello
let str = `Hello
Hello
Hello
`;
console.log(str.replace(/^Hello$/mg, 'GoodBye'));   /پترن رشته رو شناخت و بدلیل استفاده از 
// فلگ g 
// تمامی مقادیر متغییر
// str تغییر کرد
 //GoodBye GoodBye GoodBy

 

مثال عملی (اعتبار سنجی فرم):

index.html

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
  <link rel="stylesheet" href="style.css">
  <title>Document</title>
</head>

<body>
  <div class="container">
    <form action="#" class="form-group">
      <div class="input-group">
        <input class="form-control" type="text" name="" id="username" placeholder="Enter Username">
                <span>Username is not valid</span>
      </div>
      <div class="input-group">
        <input class="form-control" type="password" name="" id="password" placeholder="Enter Password">
        <span>must contain a lowercase ,uppercase letter and a number</span>
      </div>
      <div class="input-group">
        <input class="form-control" type="text" name="" id="phonenumber" placeholder="Enter Phone Number">
        <span>the phone number must be in the format of +9809309990000</span>
      </div>
      <div class="input-group">
        <input class="form-control" type="email" name="" id="email" placeholder="Enter Email">
        <span>must be a valid email address</span>
      </div>
      <div class="input-group">
        <input type="submit" class="form-control btn btn-custom" name="" id="btn" value="Submit">
      </div>
    </form>
  </div>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
  <script src="app.js"></script>
</body>

</html>

 

style.css

* {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
}

body {
  background: rgb(3, 13, 36);
}

span {
/*   color: rgb(243, 237, 237); */
  color:brown;
}

.container {
  width: 40%;
  margin: 300px auto;
}

.container form {
  width: 100%;
}

.container form .input-group {
  width: 100%;
  margin: 5px 0;
}

.container form .input-group .form-control {
  border-radius: 3px;
}

.container form .input-group .form-control:focus {
  outline: none;
}

.container form .input-group .form-control::placeholder {
  color: rgb(49, 47, 47);
}

.container form .input-group .btn-custom {
  background: brown;
  color: aliceblue;
  margin: 8px 0;
}

app.js


const usernameInput = document.getElementById("username");
const passwordInput = document.getElementById("password");
const phonenumberInput = document.getElementById("phonenumber");
const emailInput = document.getElementById("email");

// validations

// must be contain letters a-z in lowercase or also contain digit 0-9 of username or you can also useing _

function isValidUsername(username) {
  // return /^[a-zA-Z]{5,16}$/.test(username); //only lowercase letter and capitalize letter​ from 5 to 16 character is valid
  //فقط حروف بزرگ و کوچک مجاز است و حداقل 5 الی 16 کاراکتر مجاز است
    return /^(?!.*\.\.)(?!.*\.$)[^\W][\w.]{5,16}$/.test(username); //this pattern is for username validation Instagram, and recommended
  //این پترن برای اعتبار سنجی ایسنتاگرام هست و پیشنهاد میشه 
}

//must contain a lowercase ,uppercase letter and a number
function isValidPassword(password) {
  // return /[a-z]/.test(password) && /[A-Z]/.test(password) && /[0-9]/.test(password);
  return /^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$/.test(password);
}
//the phone number must be in the format of +9809309990000
function isValidPhoneNumber(phonenumber) {
  // return /^(\+98|0)?0?9\d{9}$/.test(phonenumber);
  // OR The following pattern is suggested
  // میتونید از پترن بالا یا پایینی استفاده کنید اما پایینی پیشنهاد میشه
  return /^(\+?98|0)?0?9\d{2}\d{3}\d{4}$/.test(phonenumber);
}
// must be a valid email address
function isValidEmail(email) {
  return /^[^@#!$%^&*()_+="'`*\s]+@[^@#!$%^&*()_+="'`*\d\s]+\.[a-z]+$/.test(
    email
  );
  // up there this line we via put special characters like #$@% and etc in the pattern, we limited them for ourselves to using them in input field
  //بالای این خط ما کاراکتر های خاص مانند
  //#$@ُ
  // را دروون پترن قرار دادیم که باعث محدود شدن استفاده از انها در اینپوت میشه
}

// formating functions
function formatPhoneNumber(text) {
  const regex = /^(\+?98|0)?(0?9\d{2})(\d{3})(\d{4})$/;
  return text.replace(regex, "($1) $2-$3-$4"); //this line is code for formatting code link (+98)0911-000-1231
  // Tip: if you want to change code after formatting, your faced with this error below input field -> the phone number must be in the format of +9809309990000
  //توجه:اگر بخواهید کد را بعد از اینکه فرمت شده تغییر بدید با اروری که زیر فیلد اینپوت هست مواجه خواهید شد
}

// set up events
function showOrHideTip(show, element) {
  if (show) {
    element.style.display = "inherit";
  } else {
    element.style.display = "none";
  }
}

function createListener(validator) {
  return (e) => {
    const text = e.target.value;
    const valid = validator(text);
    const showTip = text !== "" && !valid;
    const tooltip = e.target.nextElementSibling;
    showOrHideTip(showTip, tooltip);
  };
}
usernameInput.addEventListener("input", createListener(isValidUsername));
passwordInput.addEventListener("input", createListener(isValidPassword));
phonenumberInput.addEventListener("input", createListener(isValidPhoneNumber));
phonenumberInput.addEventListener("blur", (e) => {
  e.target.value = formatPhoneNumber(e.target.value);
});
emailInput.addEventListener("input", createListener(isValidEmail));

 

خب امیدوارم از این مجموعه اموزش های Regular Expressions لذت برده باشید و بکارتون اومده بشه سعی کردم در این اموزش اکثر مواردی رو که نیازه پوشش بدم پیشنهاد یا انتقادی هم بود زیر همین پست درج کنید .