ביטויים רגולריים והתאמת תבניות
pos#
מדווח או קובע היכן התאמת ה־regex /g הבאה תתחדש במחרוזת.
pos קורא (או, כ־lvalue, כותב) את ה־offset שמנוע ה־regex שומר על סקלר לאחר התאמה גלובלית (m//g, s///g). ה־offset סופר תווים, לא בתים, והוא המיקום אחרי ההתאמה המוצלחת האחרונה - המקום שבו האיטרציה הבאה של /g תתחיל לסרוק. ללא ארגומנט pos פועל על $_.
תקציר#
pos SCALAR
pos $str = N
pos
מה מקבלים בחזרה#
offset שלם, או undef כאשר אין מיקום רשום. 0 הוא offset תקף ומשמעו ״תחילת המחרוזת״; הוא אינו זהה ל־undef, שמשמעו ״התאמת /g לא רצה, או האחרונה נכשלה ואיפסה את המיקום״. תמיד הבחינו בין השניים עם defined:
if (defined pos $str) {
# a /g scan is in progress
}
כאשר משמש כ־lvalue, pos SCALAR מחזיר מיקום הניתן להשמה:
pos($str) = 5; # next /g match starts at char offset 5
מצב גלובלי שהוא נוגע בו#
pos קורא וכותב את מיקום ה־regex לכל־סקלר המצורף לאופרנד שלו. ללא ארגומנט הוא מכוון ל־$_. ה־offset השמור הוא מה ש־\G מתעגן אליו בהתאמה הבאה, ולכן כל קריאה ל־pos עשויה לשנות היכן \G נקשר.
דוגמאות#
מהלכים על כל מילה במחרוזת עם /g בהקשר סקלר, באמצעות pos כדי לדווח על התקדמות:
my $s = "one two three";
while ($s =~ /(\w+)/g) {
printf "%-5s ends at %d\n", $1, pos $s;
}
# one ends at 3
# two ends at 7
# three ends at 13
דילוג קדימה לפני התחלת הסריקה. ההתאמה הראשונה מתחילה ב־offset 4, לא 0:
my $s = "AAA BBB CCC";
pos($s) = 4;
$s =~ /(\w+)/g;
print $1, "\n"; # BBB
עיגון התאמת המשך לקודמת באמצעות \G. בלי \G המנוע היה סורק קדימה מעבר לכל פער; איתו, ההתאמה חייבת להתחיל בדיוק היכן שהאחרונה הסתיימה:
my $s = "12ab34cd";
while ($s =~ /\G(\d+)(\w+?)(?=\d|\z)/g) {
print "num=$1 tail=$2\n";
}
# num=12 tail=ab
# num=34 tail=cd
הפעלה מחדש של סריקה על־ידי ניקוי המיקום:
pos($s) = undef; # next /g starts from offset 0 again
מקרי קצה#
posחשוף מכוון ל־$_.posבתוךwhile (<>) { ... }מדווח אפוא על המיקום בשורת הקלט הנוכחית.תווים, לא בתים. עבור מחרוזת המכילה תווים רבי־בתים,
posמחזיר את ה־offset בתווים. הפרגמה (המיושנת)use bytesעוברת ל־offsetים בבתים; קוד חדש לא צריך להסתמך עליה.התאמת
/gכושלת מאפסת את המיקום ל־undef- ה־/gהבא מתחיל מחדש ב־offset0. הוסיפו את המתאם/c(m//gc) כדי לשמר את המיקום בכישלון, וזה האידיום הרגיל בעת הרכבת מספר תבניות חלופיות מעוגנות־\Gמול אותה מחרוזת.קריאות במהלך התאמה הן מיושנות.
posמשקף את הסוף של ההתאמה הקודמת. ביטויים כמו(?{ pos() = 5 })אוs//pos() = 5/eמשפיעים על ההתאמה הבאה, לא על זו הרצה כעת.דגל התאמת אורך־אפס. קביעת
posגם מנקה את הדגל הפנימי הותאם עם אורך־אפס, כך שהתאמה ברוחב אפס נוספת באותו מיקום מותרת שוב. ראו את פרק הביצועים של מדריך ה־regex תחת סיום התאמת אורך־אפס.אופרנד שאינו lvalue.
posדורש משתנה סקלר אמיתי עבור צורת ה־lvalue;pos("literal") = 3היא שגיאת זמן הידור.Offset
0מולundef.posשל0משמעו ה־/gהבא מתחיל בהתחלה;undefמשמעו אין מיקום שנקבע. הם מתנהגים באופן זהה בהתאמה הראשונה אך נבדלים לאחר שמצב דגל התאמת־האורך־אפס נלקח בחשבון.
הבדלים מ־upstream#
תואם מלא ל־upstream Perl 5.42.
ראו גם#
m- המתאם/gהוא מה שיוצר ומקדם את המיקום ש־posקורא; המתאם/cבכישלון משמר אותוqr- הידור מקדים של תבנית פעם אחת, ולאחר מכן שימוש חוזר בה בלולאות/gמעוגנות־\Gללא פענוח חוזרsplit- הדרך היומיומית האחרת להליכה במחרוזת בחלקים; איןposמעורב, אך לעיתים קרובות בחירה נקייה יותר כשהמתחמים פשוטים-
zero-width anchor that binds to the current
pos; the main reason to touchposin the first place
$_- יעד ברירת המחדל שלposחשוף