عبارت های منظم در جاوا اسکریپت , Regular expressions in javascript

قسمت دومکلاس Date و کار با تاریخ در عبارات منظم قبل از اینکه بریم سراغ کار با کلاس Date بهتره کمی کار کنیم .برای دریافت زمان جاری current time کافیه فقط کلاس Date رو new کنید console.log(new Date()); //Sat Mar 28 2020 01:03:48 GMT+0430 (Iran Daylight Time)برای دادن تاریخ دستی (custom) میتونید مقادیری که دوست دارید رو بدیدconsole.log(new Date(2009, 11, 9)); //Mon Mar 09 2020 00:00:00 GMT+0330 (Iran Standard Time) console.log(new Date(2009, 11, 9, 12, 59, 59, 999)); //Wed Dec 09 2015 12:59:59 GMT+0330 (Iran Standard Time)توجه داشته باشید که جاوا اسکریپت ماه رو از 0 شروع میکنه یعنی همانطور که در مثال بالا دیدید ما 11 یعنی ماه نوامبر november رو دادیم اما جاوا اسکریپت ماه 12 ام میلادی یعنی دسامبر december رو به ما نمایش داده این امر یکم گیج کنندست پس مراقب باشید.همچنین همانطور که دیدید 4 ارگومان دیگه یعنی ساعت , دقیقه ,ثانیه و میکرو ثانیه اختیاری هستند همانطور که میدانید تاریخ بیشتر زبان های برنامه نویسی بر اساس قراردادی تعبیه شدن که بهش میگن تایم استمپ Timestamp این قرار داد از یونیکس تایم Unix Time پیروی میکنه که در سال 1970 بوجود اومده و بار اساس میلی ثانیه هست میتونید از شی getTime استفاده کنید تا تاریخ مورد نظرتون رو برا اساس میکرو ثانیه تحویل بده یعنی برعکس مثال های زیر رو ببینید:console.log(new Date(2020, 03, 28).getTime()); //1588015800000 console.log(new Date(1588015800000)); //Tue Apr 28 2020 00:00:00 GMT+0430 (Iran Daylight Time)همچنین میتونید تایم جاری رو به صورت میلی ثانیه از این طریق هم بگیرید :console.log(Date.now());خب دیگه بحث زمان و تاریخ رو ادامه نمیدیم میریم سراغ عبارت های منظم regular expressionsمتد 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 هم فک نکنم کاری داشته باشیم خروجی کنسول[&quothello&quot, &quothello&quot, index: 0, input: &quothello guys my name is mohammadali&quot, groups: undefined]یک مثال دیگه که امیدوارم با توجه به توضیحات بالا متوجه بشید :let dateTime = '2020-03-28'; let patt = /^(\d{4})[-./](\d{1,2})[-./](\d{1,2})$/; console.log(patt.exec(&quot2020/12/02&quot)); 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 در برنامه نویسی رو انجام میده فرض کنید ما ی سری اطلاعات داریم که شامل این موارد میشه : MohmmadReza,doctor,25میخوایم این اطلاعات رو بصورت متناوب (پشت سرهم) نشون بدیم و یا حتی نشون ندیم مثال زیر رو ببینید :let regexp = /html|php|css|java(script)?/gi; let str = &quotFirst HTML appeared, then CSS, then JavaScript&quot 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)); //[&quotgrey&quot] let reg2 = /gr(e|a)y/ig; let str2 = 'grey'; console.log(str2.match(reg2)); //[&quotgrey&quot]هر دو مثال درسته و جواب یکی خواهد بود توجه داشته باشید که حتما مقادیری رو که میخواید بصورت متناوب باشه بین پرانتز قرار بدید مثل مثال دوم این مثال رو ببینید در این مثال از پرانتز در پترن استفاده نشدهlet reg2 = /gre|ay/ig; let str2 = 'grey'; console.log(str2.match(reg2)); //[&quotgre&quot]gr(a|e)y = gr[ae]ygra|ey = gra / eyیک مثال پیشرفته تر از مثال های بالا 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(&quotBorobudur&quot.replace(/[ou]/g, &quota&quot)); //Barabadarدر مثال بالا ما از فلگ g استفاده کردیم که همانطور که میدونید تمامی مقادیری رو که منطبق(مچ) باشه رو در بر میگیره در کلمه Borobudur ما دو تا o داریم و دوتا هم u که هر چهارتای اینارو تبدیل به a کرده چون ما تو پترن گفتیم [ou] میتونیم از pipe هم که در بالاتر توضیح دادیم استفاده کنیم مثال زیر رو ببینید :console.log(&quotBorobudur&quot.replace(/o|u/g, &quota&quot)); //Barabadarچند مثال کمی پیچیده تر : console.log(&quotLiskov, Barbara\nMcCarthy, John\nWadler, Philip&quot.replace(/(\w+), (\w+)/g, &quot$2 $1&quot));خب همانطور که میدونید let s = &quotthe cia and fbi&quot 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 = &quot1 lemon, 2 cabbages, and 101 eggs&quot 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 = &quotno&quot } return amount + &quot &quot + unit; } console.log(stock.replace(/(\d+) (\w+)/g, minusOne)) //no lemon, 1 cabbage, and 100 eggsدر مثال بالا میشه خط سوم رو حذف کرد اون خط صرفا برای این نوشته شده که اگر تعداد تخم مرغ یا کلم یا لیمو بیشتر از یکی بود یکی از تعدادشون کم میکنه بحث متد replace رو همینجا خاتمه میدیم اما شاید بعدا به این بخش ی سری جزئیات اضافه بشه و ادامه ی این مباحث رو در جلسه بعد میگممنابع :https://javascript.info/regular-expressionshttps://eloquentjavascript.net/09_regexp.htmlپایان جلسه دوم