התאמה טובה יותר של תוצאות בעזרת String.prototype.matchAll()

Joe Medley
Joe Medley

בגרסה 73 של Chrome נוספה השיטה String.prototype.matchAll(). הפונקציה פועלת באופן דומה לפונקציה match(), אבל היא מחזירה מעבד (iterator) עם כל ההתאמות לביטוי הרגולרי הגלובלי או הקבוע. כך תוכלו לבצע איטרציה על התאמות בקלות, במיוחד כשאתם צריכים גישה לקבוצות תיעוד.

מה הבעיה ב-match()‎?

התשובה הקצרה היא שום דבר, אלא אם אתם מנסים להחזיר התאמות גלובליות עם קבוצות לחילוץ. הנה חידת תכנות בשבילכם. הקוד הבא הוא דוגמה לכך:

const regex = /t(e)(st(\d?))/g;
const string = 'test1test2';
const results = string.match(regex);
console.log(results);
// → ['test1', 'test2']

מריצים את הפקודה הזו במסוף ומבחינים שהיא מחזירה מערך שמכיל את המחרוזות 'test1' ו-'test2'. אם מסירים את הדגל g מהביטוי הרגולרי, מקבלים את כל הקבוצות של החזקת המידע, אבל רק את ההתאמה הראשונה. כך הוא נראה:

['test1', 'e', 'st1', '2', index: 0, input: 'test1test2', groups: undefined]

המחרוזת הזו מכילה התאמה אפשרית שנייה שמתחילה ב-'test2', אבל היא לא אצלי. עכשיו מגיע החידת: איך אפשר לקבל את כל הקבוצות לחילוץ לכל התאמה? במאמר ההסבר על ההצעה String.prototype.matchAll() מפורטות שתי גישות אפשריות. לא ארחיב עליהם כי אני מקווה שלא תצטרכו אותם עוד הרבה זמן.

String.prototype.matchAll()

איך ייראו הדוגמאות להסבר עם matchAll()? הסתכל.

const regex = /t(e)(st(\d?))/g;
const string = 'test1test2';
const matches = string.matchAll(regex);
for (const match of matches) {
  console.log(match);
}

יש כמה דברים שחשוב לזכור לגבי הנושא הזה. בניגוד ל-match() שמחזירה מערך בחיפוש גלובלי, הפונקציה matchAll() מחזירה מעבד (iterator) שעובד מצוין עם לולאות for...of. המכפיל יוצר מערך לכל התאמה, כולל קבוצות התיעוד עם כמה פריטים נוספים. אם תדפיסו אותם במסוף, הם ייראו כך:

['test1', 'e', 'st1', '1', index: 0, input: 'test1test2', groups: undefined]
['test2', 'e', 'st2', '2', index: 5, input: 'test1test2', groups: undefined]

שימו לב שהערך של כל התאמה הוא מערך באותו הפורמט בדיוק שבו מוחזר הערך על ידי match() לביטויים רגולריים לא גלובליים.

חומר בונוס

ההסבר הזה מיועד בעיקר לאנשים שמתחילים להשתמש בביטויים רגולריים או שאינם מומחים בתחום. יכול להיות ששמתם לב שהתוצאות של match() ושל matchAll() (לכל חזרה) הן מערכי נתונים עם כמה מאפיינים נוספים עם שם. בזמן הכנת המאמר הזה, שמתי לב שיש לנכסים האלה כמה חסרונות במסמכי התיעוד ב-MDN (תיקנתי אותם). הנה תיאור קצר.

index
האינדקס של התוצאה הראשונה במחרוזת המקורית. בדוגמה שלמעלה, test2 מתחיל במיקום 5, ולכן הערך של index הוא 5.
input
המחרוזת המלאה שבה matchAll() הופעל. בדוגמה שלי, זה היה 'test1test2'.
groups
מכיל את התוצאות של כל קבוצות תיעוד בעלות שם שצוינו בביטוי הרגולרי.

סיכום

אם שכחתי משהו, אפשר לכתוב לי בתגובות למטה. מידע נוסף על השינויים האחרונים ב-JavaScript זמין בעדכונים קודמים או באתר V8.