אנחנו כבר באמצע 2020 והפיצ'ר החדש של תקן ג'אווהסקריפט ES2021 כבר התקבל ובדרכו לכרום (בפיירפוקס הוא כבר נמצא). הפיצ'ר הוא פקודה קטנה שהיתה צריכה כבר להיות בג'אווהסקריפט ממזמן – פקודת replaceAll. הפקודה הזו מבצעת חיפוש והחלפה במחרוזות טקסט, אבל על כל הפעמים.
replace
אני מאמין שאין מתכנת ג'אווהסקריפט אחד שלא מכיר את replace. בגדול, היא נראית כך:
const someString = 'My name is Moshe';
const oldName = 'Moshe';
const newName = 'Yaakov';
const newStr = someString.replace(oldName, newName);
console.log(newStr); // "My name is Yaakov"
אין פה מה להסביר יותר מדי, replace היא מתודה שקיימת בכל מחרוזת טקסט ואפשר להחליף אותה כאשר היא מקבלת שני ארגומנטים. הראשון הוא הטקסט שאותו אנו רוצים להחליף והשני הוא הטקסט שנכנס במקומו (זה יכול להיות טקסט ריק ואז יש לנו מחיקה).
אבל מה הבעיה? הבעיה היא שאם אנחנו רוצים לבצע כמה החלפות, זה לא יעבוד 🙁 הנה דוגמה:
const someString = 'My name is Moshe, I love the name Moshe';
const oldName = 'Moshe';
const newName = 'Yaakov';
const newStr = someString.replace(oldName, newName);
console.log(newStr); // "My name is Yaakov, I love the name Moshe"
כלומר replace מבצע החלפה פעם אחת. אם היינו רוצים שפשוט הכל יוחלף בטקסט, הכל כולל הכל, היינו צריכים להשתמש בחיפוש ביטוי רגולרי עם פלאג גלובלי. וזה קצת מבאס:
const someString = 'My name is Moshe, I love the name Moshe';
const oldName = /Moshe/g;
const newName = 'Yaakov';
const newStr = someString.replace(oldName, newName);
console.log(newStr); // "My name is Yaakov, I love the name Yaakov"
למה זה מבאס? כי בדוגמאות hello world כאלו זה הכי קל בעולם. אבל מה קורה אם יש לי טקסטים שאני רוצה להחליף ויש בהם סימנים מיוחדים כמו ?.+\ ? אני צריך לעשות להם escaping כדי שייכנסו לביטוי הרגולרי והעניינים מסתבכים. למה אין פקודה מסודרת שאני יכול להכניס לתוכה מחרוזת טקסט וזהו?
בסטנדרט החדש ES2021 אנו מקבלים את פקודת replaceAll שאפשר להשתמש בה בקלות עם מחרוזות טקסט בלי שום ביטויים רגולריים:
const someString = 'My name is Moshe, I love the name Moshe';
const oldName = 'Moshe';
const newName = 'Yaakov';
const newStr = someString.replaceAll(oldName, newName);
console.log(newStr); // "My name is Yaakov, I love the name Yaakov"
אפשר להשתמש (כמו ב-replace) בפונקציה שמחזירה טקסט כדי שתקבע מה הטקסט המוחזר יהיה.
const someString = 'My name is Moshe, I love the name Moshe';
const oldName = 'Moshe';
const newStr = someString.replaceAll(oldName, () => 'Yaakov');
console.log(newStr); // "My name is Yaakov, I love the name Yaakov"
הפונקציה הזו, אם אתם לא מכירים אותה, היא פונקצית חץ. חלק מ-ES6 .
ב-caniuse מבשרים ש-replaceAll עובדת בפיירפוקס ובכרום החל מגרסה 85.
5 תגובות
ב web assembly זה לא היה קורה…
עובד בnode?
אני תרח זקן, קורא ביטויים רגולריים לארוחת בוקר 🙂 גם פונקציה משלך של replace all (רמז: פונקצית חץ ורקורסיה) לא מסובך לכתוב. נראה לי שאתה קצת מפונק, בקטע טוב
גם אני מת על ביטויים רגולריים, אבל replaceAll היא פונקציה שיש בכל שפה נורמלית, escaping זה לא כיף ומועד לחורי אבטחה, ולמרות שאתה צודק שקל לכתוב אחת כזו (ויש מיליון ואחת מודולים כאלה בNPM) – היא תהיה איטית יותר (טוב, נו), ובכלל אנחנו כבר כמה שנים בקטע של ליצור ספרייה סטנדרטית לJS כמו כל שפה נורמלית במקום מודול לכל דבר בNPM (ע"ע string padding, number formats…)
אני הייתי מישתמש ב
'str'.split('moahe').join('yakov')
בהחלט חידוש מרענן