ביטויים רגולריים והתאמת תבניות

m//#

חיפוש תבנית במחרוזת ודיווח האם - ומה - התאים.

m// הוא אופרטור ההתאמה. הוא מהדר את PATTERN כביטוי רגולרי (ראו מדריך ה־regex), מריץ אותו מול מחרוזת מטרה, ומחזיר ערך שצורתו נקבעת על־ידי הקשר הקריאה ועל־ידי המתאמים המוחלים. המטרה היא מה שיושב משמאל ל־=~ או !~; ללא אופרטור איגוד המטרה היא $_. ה־m המקדים הוא אופציונלי כאשר המתחם הוא /, כך ש־/PATTERN/ ו־m/PATTERN/ מציינים אותו הדבר.

תקציר#

$str =~ m/PATTERN/flags
$str =~ /PATTERN/flags
m/PATTERN/flags              # target is $_
/PATTERN/flags               # target is $_
$str =~ m{PATTERN}flags      # any paired non-word delimiters

מה מוחזר#

ההקשר קובע את צורת הערך המוחזר.

  • הקשר סקלרי, ללא /g: 1 בהתאמה, מחרוזת ריקה בלא־התאמה. שניהם שמישים כבוליאניים; המחרוזת הריקה היא שקר דו־ערכי השווה גם ל־0 מספרית.

  • הקשר רשימה, ללא /g: רשימת ערכי הלכידה ($1, $2, $3, …) בהתאמה מוצלחת; אם לתבנית אין קבוצות לכידה, היחידנית (1); בכישלון, רשימה ריקה. כך עובד if (my ($x, $y) = $s =~ /(\w+)=(\w+)/).

  • הקשר סקלרי, /g: כל קריאה מתקדמת לאורך המחרוזת, מחזירה אמת עבור ההתאמה הבאה ושקר כאשר אין יותר. pos על המטרה עוקב היכן הניסיון הבא יתחיל.

  • הקשר רשימה, /g: כל ההתאמות בירייה אחת. עם קבוצות לכידה, הרשימה השטוחה של כל הלכידות מכל התאמה. ללא לכידות, הרשימה של כל התאמה מלאה.

התאמות מוצלחות גם מאכלסות את משתני ה־regex המיוחדים ($1 עד $9, $&, $`, $', $+, %+, %-) עבור התחום הדינמי המקיף. התאמה כושלת משאירה אותם מחזיקים בערכים הקודמים שלהם - יש לבדוק תמיד את ההתאמה עצמה, לעולם לא משתנה לכידה, כדי לקבוע האם התרחשה התאמה.

מצב גלובלי שהוא נוגע בו#

  • $_ - מטרת ברירת המחדל כאשר לא ניתן איגוד =~.

  • $1, $2, … - לכידות ממוספרות, נקבעות בהצלחה, ללא שינוי בכישלון.

  • $&, $`, $' - התאמה, קדם־התאמה, פוסט־התאמה.

  • $+ - הלכידה בעלת המספר הגבוה ביותר שאכן התאימה (שימושית עם חלופות).

  • %+, %- - האשים של לכידות בעלות שם.

  • ${^LAST_SUCCESSFUL_PATTERN} - התבנית האחרונה שהתאימה בתחום הדינמי הנוכחי; גם התבנית שהצורה הריקה m// משתמשת בה מחדש (ראו מקרי קצה).

  • pos על מחרוזת המטרה - נקרא ומעודכן על־ידי התאמת /g; מאופס בכישלון אלא אם גם /c נקבע.

  • מקורות כללי Locale / Unicode כאשר /l, /u, או /d בתוקף.

מתחמים#

עם m, כל זוג תווים שאינם רווח לבן עובד כמתחם, וזוגות סוגריים מקוננים:

m/pattern/
m{pattern}
m[pattern]
m(pattern)
m<pattern>
m!pattern!
m#pattern#
m,pattern,

בחירת מתחם שאינו מופיע בתבנית נמנעת מעומס backslash - הידוע כ־LTS, leaning toothpick syndrome (תסמונת הקיסם הנשען). תבנית להתאמת נתיב נקראת נקייה עם m{…} או m!…! וגרוע עם m/…/.

שתי בחירות מתחם משנות את הסמנטיקה:

  • ' (גרש יחיד) - ללא שיבוץ משתנים בתוך PATTERN. m'$foo' מתאים את ארבעת התווים המילוליים.

  • ? - m?PATTERN? מתאים פעם אחת בלבד בין קריאות ל־reset. ה־m המקדים הוא חובה; מאז Perl 5.22 הצורה החשופה ?…? היא שגיאת תחביר.

כאשר המתחם הוא תו מילה (אות או ספרה), נדרש רווח אחרי m: m q foo q חוקי, mqfooq לא.

מתאמים#

מתאמי הידור תבנית (מתקבלים גם על־ידי qr, s, ו־split):

  • m - רב־שורתי: ^ ו־$ מתאימים בכל תו שורה חדשה מוטמע, לא רק בקצוות המחרוזת.

  • s - חד־שורתי: . מתאים כל תו כולל תו שורה חדשה.

  • i - התאמה ללא רגישות לאותיות גדולות וקטנות.

  • x - התעלמות מרווח לבן והערות # בתבנית; xx מרחיב זאת אל מחלקות תווים.

  • p - שמירת עותקים של המחרוזת שהתאימה. מאז 5.20 זוהי no-op - ${^PREMATCH}, ${^MATCH}, ${^POSTMATCH} זמינים תמיד לאחר התאמה מוצלחת.

  • a, u, l, d - כללי קבוצת תווים עבור \d, \s, \w, ומחלקות POSIX. /a מגביל אותם ל־ASCII; /aa בנוסף אוסר על התאמת ASCII/לא־ASCII תחת /i.

  • n - ללא לכידה: (…) מתנהג כמו (?:…) ואינו מאכלס את $1, $2, ….

  • o - מהדר את התבנית בדיוק פעם אחת גם אם משתנים משובצים משתנים. כמעט תמיד הכלי השגוי; יש להשתמש ב־qr כדי לבנות תבנית מהודרת רב־שימושית במקום.

מתאמי תהליך התאמה (ספציפיים ל־m// ול־s///):

  • g - התאמה גלובלית. התנהגות הקשר סקלרי איטרטיבית (מקדמת את pos בכל קריאה); התנהגות הקשר רשימה מחזירה כל התאמה בבת אחת.

  • c - משמעותי רק עם /g. התאמת /g שנכשלה משאירה את pos במקום שהיה במקום לאפס אותו להתחלה; נדרש עבור סורקי סגנון־lex הבנויים סביב \G.

דוגמאות#

בדיקה האם מחרוזת מכילה תבנית:

if ($line =~ /error/i) {
    warn "matched: $line";
}

כריכת לכידה בפעולה אחת:

if (my ($key, $val) = $line =~ /^(\w+)\s*=\s*(.*)$/) {
    $config{$key} = $val;
}

שליפת כל מספר ממחרוזת עם /g בהקשר רשימה:

my @nums = "x=1 y=22 z=333" =~ /(\d+)/g;
# @nums = (1, 22, 333)

איטרציה על התאמות אחת בכל פעם עם /g בהקשר סקלרי, באמצעות pos כדי לראות היכן נמצא המנוע:

my $s = "foo 1 bar 22 baz 333";
while ($s =~ /(\d+)/g) {
    printf "matched %s at offset %d\n", $1, pos($s) - length($1);
}

צורה מורחבת עם המתאם x ולכידות בעלות שם:

if ($ts =~ m{
        ^ (?<year>\d{4}) -
          (?<mon> \d{2}) -
          (?<day> \d{2}) $
    }x) {
    printf "year=%s mon=%s day=%s\n", $+{year}, $+{mon}, $+{day};
}

הימנעות מ־LTS על־ידי בחירת מתחם שאינו מופיע בתבנית:

next if $path =~ m{^/usr/local/};

שימוש ב־\G עם m//gc כדי ללכת לאורך מחרוזת טוקן־אחר־טוקן בלי לאבד מיקום בזרוע כושלת:

while (1) {
    if    ($s =~ /\G(\d+)/gc)    { push @tok, ['num',  $1] }
    elsif ($s =~ /\G(\w+)/gc)    { push @tok, ['word', $1] }
    elsif ($s =~ /\G(\s+)/gc)    { next                   }
    else                         { last                   }
}

מקרי קצה#

  • תבנית ריקה: // ו־m// משתמשים מחדש בתבנית האחרונה שהתאימה בהצלחה בתחום הדינמי הנוכחי. אם דבר עדיין לא התאים, תבנית ריקה מתאימה בכל מקום. העברת קלט משתמש ישירות אל m/$pat/ כאשר $pat עלול להיות ריק היא קצה חד - יש לעטוף בקבוצה שאינה לוכדת: m/(?:$pat)/. התבנית המוצלחת האחרונה קריאה גם כ־${^LAST_SUCCESSFUL_PATTERN}.

  • דו־משמעות defined-or: Perl פותר $x // $y כאופרטור defined-or, אף פעם לא כשתי התאמות ריקות. במיקומים פתולוגיים (print $fh //) Perl עדיין מניח defined-or; ניתן לכפות התאמה על־ידי כתיבת m// במפורש או הפרדת המתחמים ברווחים.

  • התאמה כושלת משאירה לכידות מיושנות: $1 אחרי /…/ כושל עדיין מחזיק את הלכידה מההתאמה המוצלחת הקודמת - יש לשעֵר תמיד את השימוש בלכידה על תוצאת ההתאמה.

  • /o עם משתנים משתנים: m/$x/o נועל את הערך הראשון של $x לתבנית המהודרת. שינויים מאוחרים יותר ב־$x מתעלמים מהם בשקט. יש להישען על qr במקום זאת כאשר רוצים הידור מפורש ורב־שימושי.

  • שיבוץ כאשר המתחם הוא ': m'$var' היא התאמה של דולר־var מילולי. זה רק לעתים רחוקות מה שרוצים, ואותו אפקט זמין עם \Q…\E או quotemeta בכל מתחם אחר.

  • /g בתוספת שינוי המטרה: שינוי המטרה בין איטרציות /g מאפס את pos להתחלה. יש לבצע איטרציה על עותק אם נדרש לשנות את המקור תוך כדי.

  • \G מחוץ ל־/g: ללא /g, \G מעגן ב־pos שהיה למטרה בזמן הקריאה ומתאים לכל היותר פעם אחת. במחרוזת שמעולם לא הוחל עליה /g, \G שקול ל־\A.

  • תחום איפוס של m?…?: reset מנקה את מצב m?? רק עבור החבילה הנוכחית. m?? בחבילה אחת אינו מושפע מ־reset שנקרא מאחרת.

  • אופרטורי השוואה ליד regex ריק: $x //= 1 הוא תמיד השמת defined-or; אם באמת רוצים את ה־regex הריק, יש לכתוב m// ולא //.

הבדלים מהמעלה־הזרם#

תאימות מלאה עם Perl 5.42 מהמעלה־הזרם.

ראו גם#

  • qr - הידור תבנית פעם אחת ושימוש מחדש בה; נמנע מ־/o ושומר על התבנית כערך מהמעלה הראשונה

  • s - אותו תחביר תבנית, מחליף את מה שמתאים

  • tr - תרגום תו־אחר־תו; כלי שונה עם צורה דומה למראית עין

  • split - כאשר רוצים את החלקים שבין ההתאמות ולא את ההתאמות עצמן

  • pos - קריאה או קביעה של המיקום ש־/g חוזר ממנו להתאמה

  • Regular expressions guide

    • the regex language itself: assertions, character classes, backreferences, named captures