💻 آخرین فرصت یادگیری برنامه‌نویسی با آفر ویژه قبل از افزایش قیمت (🎁 به همراه یک هدیه ارزشمند )
۰ ثانیه
۰ دقیقه
۰ ساعت
۱ رعنا شهرام فر
متوجه نشدن بخشی از درس
جامعه جاوا اسکریپت ایجاد شده در ۲۴ آبان ۱۴۰۳

سلام دقیقه 30 به بعد درمورد کدهای زیر گفتن که میتونه در کل متن سرچ کنه و همه موارد match شده رو یکجا برگردونه اما خود کد و نحوه کارش رو متوجه نشدم

function multiMatchReg(rex, text) {

                let match;

                let results = [];

                while(match !== null) {

                    match = rex.exec(text);

                    if(match !== null) {

                        results.push(match);

                    }

                }

                return results;

            }

سلام،

بطور کامل و قدم به قدم توضیح میدم که چه اتفاقی میوفته:

rex: این همون عبارت منظم (regex) هست که می‌خوای باهاش توی متن سرچ کنی.

text: این همون متنیه که می‌خوای توش جستجو کنی.

هدف این کد اینه که همه جاهایی که با عبارت منظم (rex) مطابقت دارن رو توی متن پیدا کنه و همه اون‌ها رو یکجا توی یک آرایه به اسم results ذخیره کنه.

 

تعریف متغیرها:

let match;
let results = [];

اینجا دو تا متغیر تعریف شده:

match: این متغیر قراره نتیجه هر بار تطابق (match) رو نگه داره.

results: یه آرایه هست که همه تطابق‌ها رو جمع می‌کنه تا در نهایت به عنوان نتیجه خروجی بده.

 

حلقه while:

while (match !== null) {
   match = rex.exec(text);
   if (match !== null) {
       results.push(match);
   }
}

حلقه while اینجا برای پیدا کردن همه تطابق‌ها توی متن (text) استفاده شده.

توی هر تکرار این حلقه، از دستور rex.exec(text) استفاده می‌کنه تا یک تطابق جدید پیدا کنه.

rex.exec(text) یعنی "برو و اولین بخشی از متن که با الگوی rex مطابق هست رو پیدا کن".

match نتیجه این عملیات هست و اطلاعات اون تطابق رو تو خودش ذخیره می‌کنه.

چرا while (match !== null)؟

اینجا نکته‌اش اینه که حلقه ادامه پیدا می‌کنه تا وقتی که تطابق دیگه‌ای پیدا بشه.

هر بار که یک تطابق پیدا می‌کنه (match مقداری غیر از null داره) و اون رو توی آرایه results اضافه می‌کنه.

وقتی که دیگه هیچ تطابقی توی متن پیدا نشه، rex.exec(text) مقدار null رو برمی‌گردونه و حلقه متوقف میشه.

چرا exec و حلقه while؟

rex.exec() این قابلیت رو داره که هر بار که اجراش می‌کنی، بعدی رو برات پیدا کنه.

با کمک while می‌تونیم این exec رو تکرار کنیم تا زمانی که دیگه چیزی برای پیدا کردن نمونه.

 

ذخیره تطابق‌ها در results:

if (match !== null) {
   results.push(match);
}

این if باعث میشه که هر بار که یک تطابق معتبر (یعنی match مقداری غیر از null داشته باشه) پیدا شد، اون رو توی آرایه results اضافه کنه. در نهایت، این آرایه همه تطابق‌ها رو ذخیره می‌کنه.

 

برگرداندن نتیجه:

return results;

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

نکته مهم:

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

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

به عبارت دیگه، اگر return رو داخل حلقه while بذاریم:

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

مثلاً:

while (match !== null) {
    match = rex.exec(text);
    if (match !== null) {
        results.push(match);
        // return results;  <-- اگر اینجا return کنیم، تابع متوقف می‌شود و فقط اولین match برگردانده می‌شود.
    }
}
// return بعد از حلقه
return results;  // اینجا وقتی همه جستجوها انجام شد، کل آرایه برگردانده می‌شود.

پس نتیجه‌گیری: return خارج از حلقه قرار گرفته تا همه تطابق‌ها در آرایه ذخیره بشه و در نهایت، فقط یکبار و به صورت کامل برگردونده بشه. به این صورت، همه تطابق‌ها را داریم و می‌تونیم باهاشون کار کنیم.

 

حالا توضیحات تکمیل شد. یه مثال ساده برای این تابع بیارم:

فرض کن توی متن زیر می‌خوای کلمه "cat" رو پیدا کنی:

let text = "cat in the hat, another cat, and one more cat";
let regex = /cat/g;
let result = multiMatchReg(regex, text);
console.log(result);

regex میگه دنبال کلمه "cat" بگرد، و g یعنی global که یعنی همه جاهای متن رو بگرد.

وقتی این تابع اجرا بشه، results شامل همه جاهایی میشه که کلمه "cat" پیدا شده.

محسن موحد ۲۶ آبان ۱۴۰۳، ۰۹:۴۳