מניפולציה על תוצאה של חיפוש בביטוי רגולרי
-
אני מעוניין לבצע פעולות מסוימות של חרוזות שאני מקבל בעת חיפוש עם ביטוי רגולרי.
אני מדבר כרגע על JS, אבל לאו בדווקא.למשל, הביטוי הבא:
/==([^=]+)==/g
ימצא מחרוזות מהמבנה ==1==, ==2==, ==3==, וכדומה. כאשר מה שנמצא בתוך הסוגריים זה קבוצה שאני יכול להתייחס אליה באמצעות $1.
למשל:var str = "==1==, ==2==, ==3==" srt.replace (/==([^=]+)==/g, "--$1--")
יחזיר לי את התוצאה:
"--1--, --2--, --3--"במקרה הזה, הפונקציה ריפלייס יודעת לזהות שה$1 שבתוך המחרוזת שבפרמטר השני שלה, הוא בעצם משתנה שמכיל קבוצה מתוך הביטוי הרגולרי שנתתי לה בפרמטר הראשון. אגב, אין לי מושג איך ועל פי מה קורה הזיהוי הזה.
אבל מה קורה אם אני רוצה לבצע פעולה אחרת. אני לא רוצה לשנות את הטקסט שסביב הקבוצה (ה$1), אלא את הקבוצה עצמה. למשל, בדוגמה שלמעלה, אני רוצה להכפיל כל ספרה ב3.
ולכן מהמחרוזת:
"==1==, ==2==, ==3=="
אני רוצה לקבל:
"==3==, ==6==, ==9=="לכאורה זה פשוט, אני רק צריך לעשות פונקציית הכפלה על ה$1, אבל כנראה שזה לא עובד כך. ברגע שאני עושה איזו פעולה על ה$1 הוא מפסיק להיות מזוהה כמשתנה של קבוצת התווים מתוך התוצאה הספציפית של הביטוי הרגולרי, ומזוהה בטקסט סתם.
למשל, במקרה הזה, ניסיתי:var str = "==1==, ==2==, ==3==" srt.replace (/==([^=]+)==/g, "$1"*3)
וזה לא פעל. כי הקוד פוענח כאילו אני מכפיל מחרוזת "$1" *3 ולא כאילו אני מכפיל משתנה בשם $1 המכיל בתוכו ספרה.
אני מניח שהתשובה פשוטה, למי שמבין כיצד עובד הזיהוי של תוצאת החיפוש הרגולרי, כלומר לא לי.
תודה ושבוע טוב -
בJS, הפרמטר השני של replace מקבל או טקסט להחלפה די סטטית (רוב מה שאפשר לעשות באפשרות הזו היא שרשור של הקבוצות הרצויות שנלכדו בסדר הרצוי), או פוקנציה לבחירת הפלט המדוייק להחזרה בכל החלפה.
במידה ואתה בוחר באפשרות הטקסט, אתה צריך בסופו של דבר לתת נטו טקסט. בחיים לא תצליח לבטא בטקסט או בשפת רגקס פעולה כזו של המרה למספר והכפלה.
באפשרות של פונקציה אתה מקבל פונקציה שהפרמטר הראשון שלה הוא האובייקט match, והבאים אחריו זה הקבוצות. למשל, במקרה שלך כזו פונקציה:function RepMulti(m, group1){ return parseInt(group1) * 3; }
ואז בreplace:
srt.replace (/==([^=]+)==/g, RepMulti);
-
@davidnead אמר במניפולציה על תוצאה של חיפוש בביטוי רגולרי:
אגב, אין לי מושג איך ועל פי מה קורה הזיהוי הזה.
מאוד פשוט. כמו שטוקנים מיוחדים מזוהים במחרזות החיפוש כהוראות חיפוש, כך טוקנים מיוחדים בהחלפה. והסימן דולר שאחריו באה ספרה משמש כטוקן ל"טקסט שנמצא בקבוצה X במופע הנוכחי של החיפוש".
-
@dovid אמר במניפולציה על תוצאה של חיפוש בביטוי רגולרי:
אתה מקבל פונקציה שהפרמטר הראשון שלה הוא האובייקט match, והבאים אחריו זה הקבוצות
תודה! זה בדיוק הידע שהיה חסר לי. אבל עדיין לא הבנתי אותו עד הסוף.
- מה זה בדיוק האובייקט mach שאני מקבל בפרמטר הראשון?
- הקבוצות, פשוט משורשרות כפרמטרים לפי הסדר?
- מה המשמעות שאני קורא לפונקציה בלי סוגריים במקרה הזה? לכאורה ההתנגהות היא כאילו כן קראתי לה עם סוגריים ופרמטרים רק שהתוכנה "מכניסה" לה פרמטרים לבד.
-
-
זה אובייקט JS שמכיל את כל המידע על התוצאה הנתונה כולל הקבוצות. פרמטרי ההמשך הם לנוחות.זה מכיל את כלל התוצאה, כמו הטוקן $&. -
כן בדיוק כמו טוקן ה$1, $2... שיש בהחלפה. בJS קבוצות הREGEX מזוהות אך ורק לפי המיקום - סדר שלהם.
-
אם אתה קורא לפונקציה עם סוגריים, אתה לא מעביר בפרמטר פונקציה אלא תוצאה שלה. שורה תחתונה פונקציית הreplace תקבל ערך ולא פוקנציה. כדי שהיא תקבל פונקציה, שהיא תוכל להפעיל בכל מופע שיימצא, אתה חייב לתת לה מצביע לפונקציה ולא להפעיל אותה מראש. העברת פונקציות מאוד שכיחה בJS בגלל האסיכרניות שלה ובגלל הקלות לעשות זאת, אלא שזה יותר מוכר בסינטקס שכותבים את הפונקציה עצמה ולא את שמה, במקרה שלנו ככה:
srt.replace (/==([^=]+)==/g, function RepMulti(m, group1){ return parseInt(group1) * 3; });
אני משער שהתחביר הזה מוכר לך היטב.
אגב כיום בזכות ES6 אז אפשר לכתוב אלגנטי יותר, בתחביר פונקציית חץ שחוסך הרבה בלגן סינטקסי:srt.replace (/==([^=]+)==/g, (m, group1) => parseInt(group1) * 3);
-
-
@dovid אמר במניפולציה על תוצאה של חיפוש בביטוי רגולרי:
זה אובייקט JS שמכיל את כל המידע על התוצאה הנתונה כולל הקבוצות
תוכל להרחיב טיפה? (מקסימום תעתיק אח"כ למדריך הרגקס ) לא מכיר את האובייקט הזה והשימוש בו. איך יכולתי למשל להשתמש בו כאן במקום פרמטרי ההמשך.
-
@davidnead אמר במניפולציה על תוצאה של חיפוש בביטוי רגולרי:
@dovid אמר במניפולציה על תוצאה של חיפוש בביטוי רגולרי:
זה אובייקט JS שמכיל את כל המידע על התוצאה הנתונה כולל הקבוצות
תוכל להרחיב טיפה? (מקסימום תעתיק אח"כ למדריך הרגקס ) לא מכיר את האובייקט הזה והשימוש בו. איך יכולתי למשל להשתמש בו כאן במקום פרמטרי ההמשך.
אני טועה, הפרמטר הראשון לא אובייקט אלא פשוט טקסט שמכיל את כלל התוצאה (מקביל ל$& בJS או $0 במנועי רגקס אחרים).
בקשר למדריך, אכן זה מתוכנן (כבר היה לו התחלה שנמחקה בעקבות המשבר שהאתר חוה שבוע שעבר).
-
@davidnead אמר במניפולציה על תוצאה של חיפוש בביטוי רגולרי:
בהמשך לנ"ל, שאלה קצת טפשית:
איך אני בונה מערך, שמכיל 'רק' את התוצאות שמצאתי על ידי חיפוש בביטוי הרגולרי?
אני יכול כמובן לעשות לולאה שתשרשר למערך בכל פעם את התוצאה המוחזרת בפרמטר הראשון שהזכרת, אבל מן הסתם יש דרך קלה יותר...חייבים לעשות לולאה אבל לדעתי לא כפי שרצית (בפונקציית ההחלפה), כי זה עבור החלפה, וזה שימוש 'טריקי'.
הלולאה צריכה להיות ע"י יצירת משתנה של RegExp, ואח"כ לולאה כל עוד הexec שלו איננו ריק. הלולאה הזו מסוכנת: במידה והRegExp איננו מוגדר במשתנה אלא נוצר בכל סיבוב (למשל ע"י שימוש ב//, במקום במשתנה Js) או אם הביטוי לא מכיל את הדגל g - שמציין שהביטוי אמור להחזיר את כלל התוצאות ולא רק את הראשונה, הלולאה תהיה אין סופית ותביא לקריסת דף האינטרנט מיידית.var reg = /\d/g; //הכנסת הביטוי למשתנה var results = []; //מערך תוצאות var one; //אחסון לכל תוצאה בתורה if(reg.global) while(one = reg.exec(text)) //זה מחזיר כל פעם את התוצאה הבאה results.push(one);
יש לציין שגם match פשוט של טקסט מחזיר מערך של תוצאות אבל התוצאות הם רק הקבוצה 0 ($&) וממילא בהרבה מקרים איננה טובה.