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

qr//#

מהדר תבנית פעם אחת ומחזיר עצם regex שניתן לעשות בו שימוש חוזר.

qr// מצטט את ה־STRING שלו כביטוי רגולרי, משלב אותו באותה דרך ש־m עושה, ומחזיר עצם Regexp שניתן לאחסן, להעביר, ולשלב בתבניות אחרות. התבנית המהודרת נושאת עמה את המתאמים שלה, אז כל שימוש מאוחר רואה את הדגלים שהתבנית נבנתה עמם.

תקציר#

my $re = qr/STRING/;
my $re = qr/STRING/msixpodualn;
my $re = qr{STRING};
my $re = qr'STRING';            # single-quote delimiter: no interpolation

מה מקבלים בחזרה#

עצם Regexp ש־blessed עליו. ref מחזיר את המחרוזת "Regexp". המרת העצם למחרוזת מניבה צורה מנורמלת של התבנית עם המתאמים שלה מקודדים בעטיפת (?flags:...), שזו בדיוק הצורה שמנוע ה־regex משלב כאשר העצם משולב לתבנית אחרת:

my $re = qr/my.STRING/is;
print $re;                      # (?^si:my.STRING)

העצם אטום - אל תעשו לו dereference. הצורה המומרת־למחרוזת מיועדת לשילוב ולניפוי, לא לפענוח ידני.

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

  • $1, $2, …, $+, $&, $`, $', %+, %- - אינם נקבעים על־ידי qr// עצמו. הידור אינו ביצוע התאמה. אלה מאוכלסים רק כאשר התבנית המהודרת משמשת מאוחר יותר על־ידי m, s, או split.

  • $@ - נקבע אם התבנית מכילה שגיאת תחביר והשגיאה נלכדת עם eval. שגיאת הידור שלא נלכדה מעלה חריגה קטלנית בסגנון Bareword "..." not allowed בנקודת ה־qr//.

  • פראגמות locale ו־Unicode שבתוקף באתר ה־qr// (use locale, use utf8) נאפות לתוך העצם המהודר. שינוי הפראגמה מאוחר יותר אינו משנה את העצם.

מתאמים#

כל המתאמים החלים על m חלים גם על qr//. הם נלכדים בעצם המוחזר ומתפשטים כאשר העצם משולב לתבנית אחרת.

דגל

משמעות

m

רב־שורות: ^ ו־$ מתאימים בירידות שורה פנימיות.

s

שורה־בודדת: . מתאים לירידת שורה.

i

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

x

מורחב: רווחים והערות # מוזנחים בתבנית. xx גם מתעלם מרווחים בתוך [...].

p

שמירת־התאמה (חסר־פעולה ב־Perl 5.20+; ${^PREMATCH}, ${^MATCH}, ${^POSTMATCH} זמינים תמיד).

o

מהדר פעם אחת; משתנים משולבים מוקפאים בשימוש הראשון. נדרש לעיתים נדירות - qr// כבר מטמין.

a

מגביל ל־ASCII את \d, \s, \w, ומחלקות POSIX. aa אוסר נוסף על התאמות ASCII־ל־לא־ASCII תחת i.

l

שימוש בכללי ה־locale הנוכחי.

u

שימוש בכללי Unicode.

d

כללי ברירת מחדל כפולים (legacy; בדרך כלל נקלטים אוטומטית).

n

ללא־לכידה: קבוצות (...) ללא שם אינן ממלאות את $1, $2, ….

כאשר תבנית מהודרת מוטמעת בתבנית גדולה יותר, סט התווים והדגלים msixn שאיתם נבנתה נשארים בתוקף עבור אותו טווח בלבד. המתאם o הוא החריג היחיד - הוא אינו מתפשט.

דוגמאות#

הידור פעם אחת, שימוש פעמים רבות. לולאה על תבניות שנבנו מראש נמנעת מהידור מחדש בכל איטרציה:

my @rules = map qr/$_/i, qw(error warn fail panic);
for my $line (@lines) {
    for my $rx (@rules) {
        print $line if $line =~ $rx;
    }
}

שילוב תבנית מהודרת בתוך תבנית אחרת. התבנית החיצונית רואה את דגלי התבנית הפנימית דרך עטיפת ה־(?flags:...):

my $word = qr/\w+/;
my $csv  = qr/^$word(?:,$word)*$/;
"alpha,beta,gamma" =~ $csv;         # matches

מתחם מירכאות בודדות עבור תבנית מילולית ללא שילוב - שימושי כאשר התבנית מכילה $ או @ שחייבים להישאר מילוליים:

my $price = qr'\$\d+\.\d{2}';       # matches "$1.99", not a sigil
"total: \$9.95" =~ $price;          # matches

שימוש חוזר בתבנית בין קריאות. אחסון הצורה המהודרת ב־closure פורש את ההידור על־פני כל קריאה לתת־השגרה המוחזרת:

sub matcher_for {
    my $pat = shift;
    my $rx  = qr/\Q$pat\E/i;        # \Q...\E quotes regex metacharacters
    return sub { $_[0] =~ $rx };
}

my $is_error = matcher_for("ERROR:");
$is_error->($line);

לכידה בתוך qr// משולב עדיין מאכלסת את $1 בזמן ההתאמה, לא בזמן ה־qr//:

my $num = qr/(\d+)/;
"port 8080" =~ /:$num$/;
print $1;                           # 8080

שימוש ב־/n כדי לדכא לכידה ב־$1, $2, … תוך שמירת לכידות בעלות שם זמינות:

my $rx = qr/(foo)(?<kw>bar)/n;
"foobar" =~ $rx;
print $+{kw};                       # "bar"
print defined $1 ? "yes" : "no";    # "no"

מקרי קצה#

  • אין התאמה בזמן הידור. qr// רק מהדר. כדי לבדוק מחרוזת, השתמשו בעצם עם m או =~: $string =~ $rx.

  • משתנים משולבים נלכדים בזמן ה־qr//, לא בזמן השימוש. my $rx = qr/$pat/; $pat = "other"; משאיר את $rx מחזיק את התבנית שנבנתה מה־$pat המקורי. כדי ללכוד מחדש, בנו מחדש את ה־qr//.

  • שגיאות תבנית בזמן הידור הן קטלניות. qr/(/ מעלה חריגה באתר ה־qr//. עטפו ב־eval כאשר התבנית מגיעה מקלט משתמש ושגיאה צריכה להיות ניתנת לשחזור:

    my $rx = eval { qr/$user_input/ };
    die "bad pattern: $@" if $@;
    
  • ref($rx) מחזיר "Regexp" - לא "SCALAR", לא "CODE". השתמשו בזה לזיהוי תבנית מהודרת בחריץ ארגומנט פולימורפי: ref($arg) eq 'Regexp'.

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

  • צריבת locale ו־Unicode. qr// שנבנה בתוך use locale מתנהג עם כללי locale לתמיד, גם כאשר משתמשים בו מחוץ לאותו תחום. בנו מחדש תחת הפראגמה הרצויה אם ההתנהגות צריכה להשתנות.

  • \Q...\E עבור טקסט מילולי. כדי להדר תבנית המתאימה למחרוזת שסופקה על־ידי המשתמש מילולית, עטפו אותה ב־\Q...\E: qr/\Q$literal\E/. ללא \Q, מטה־תווים במחרוזת מתפרשים כתחביר regex.

  • תבנית ריקה. qr// מהדר לתבנית הריקה, שמטופלת באופן מיוחד בזמן ההתאמה: $str =~ $empty משתמש מחדש בתבנית המוצלחת האחרונה באותו תחום. זוהי התנהגות זמן־ההתאמה של m, לא תכונה ספציפית של qr//, אך זוהי מלכודת נפוצה כשמעבירים qr// ברירת מחדל.

הבדלים מהמקור#

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

ראו גם#

  • m - התאמת תבנית מהודרת או תבנית מילולית מול מחרוזת; הצרכן הראשי של עצם qr//

  • s - החלפה באמצעות תבנית מהודרת; מקבל qr// בחריץ החיפוש

  • split - פיצול על תבנית מהודרת; צורת ה־qr// היא היעילה ביותר

  • Regular expressions guide

    • full regex syntax reference; read this for the meaning of the modifiers and escape sequences

  • ref - מחזיר "Regexp" עבור עצם qr//; בדיקת הטיפוס הסטנדרטית

  • eval - עטיפת qr// כאשר מקור התבנית בלתי־מהימן ושגיאת הידור צריכה להיות ניתנת לשחזור