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

Joe Medley
Joe Medley

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

מה הבעיה ב-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() מחזירה איטרטור שעובד יפה עם לולאות 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.