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

s///#

מחפש תבנית במחרוזת ומחליף כל התאמה בהחלפה.

s/// הוא אופרטור ההחלפה של Perl. הוא מוצא טקסט המתאים ל־PATTERN במחרוזת היעד, מחליף כל התאמה ב־REPLACEMENT, ובברירת מחדל מחזיר את מספר ההחלפות שבוצעו. ללא יעד מפורש (ללא =~ או !~), הוא פועל על $_. היעד חייב להיות סקלר lvalue - משתנה, איבר מערך או האש, או substr / השמה המייצרת אחד - אלא אם הדגל /r נמצא בשימוש, אשר עובד על כל ערך ומחזיר את העותק המשונה.

תקציר#

s/PATTERN/REPLACEMENT/FLAGS
$str =~ s/PATTERN/REPLACEMENT/FLAGS
$str !~ s/PATTERN/REPLACEMENT/FLAGS
my $copy = $str =~ s/PATTERN/REPLACEMENT/r

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

בברירת מחדל, ספירת ההחלפות שבוצעו כמספר שלם: 0 כאשר שום דבר לא התאים (שהוא שקר בהקשר בוליאני), מספר שלם חיובי בהצלחה. סקלר היעד משונה במקום.

עם הדגל /r, הסמנטיקה מתהפכת: היעד אינו משונה, והאופרטור מחזיר את המחרוזת (אולי משונה). אם שום דבר לא התאים, /r עדיין מחזיר עותק של המקור. תוצאת /r היא תמיד מחרוזת רגילה, אפילו כאשר המקור הוא משתנה מקושר או עצם bless עם overloading.

!~ הופך את המובן הבוליאני של ערך ההחזרה: הוא מניב אמת כשלא הוחלף דבר, שקר כשהתרחשה החלפה אחת לפחות. היעד עדיין משונה בכל מקרה.

my $n = ($text =~ s/foo/bar/g);     # count of replacements
my $out = $text =~ s/foo/bar/r;     # copy-and-modify, $text untouched

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

  • $_ - היעד בברירת מחדל כשלא ניתן =~ או !~. s/old/new/ ללא כבילה קורא וכותב $_.

  • $&, [`$``](../perlvar), [`$«`](../perlvar), [`$1`](../perlvar) וחבריהם - מוגדרים על ידי כל התאמה מוצלחת, באותה דרך ש־[`m//`](m) מגדיר אותם. בתוך `REPLACEMENT` הם מתייחסים להתאמה הנוכחית, לא לקודמת.

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

  • ה־תבנית המוצלחת האחרונה - בשימוש כאשר PATTERN מוערכת למחרוזת הריקה (s//new/ משתמש מחדש ב־regex המוצלח האחרון מהתיחום הזה).

  • $/, $\ ומפרידי פלט אינם נגועים - s/// מייצר מחרוזת, הוא אינו כותב אחת.

דגלים#

הסט המלא הוא msixpodualngcer. דגלים בצד ההתאמה מתנהגים בדיוק כמו ב־m// וב־qr; ראו את פרק המתאמים של מדריך ה־regex לפרטי צד ההתאמה. דגלים ספציפיים להחלפה:

  • e - מעריך את REPLACEMENT כבלוק של קוד Perl. ערך הבלוק הוא מחרוזת ההחלפה. שקול לעטיפתו ב־do { ... } ולהפיכת התוצאה למחרוזת.

  • ee - מעריך כקוד, אחר כך עושה eval שוב למחרוזת המתקבלת. שקול ל־eval(do { REPLACEMENT }). מתאמי e נוספים מוסיפים שכבות eval נוספות.

  • r - לא הרסני: משאיר את היעד ללא שינוי ומחזיר את העותק המשונה (או עותק ללא שינוי בהיעדר התאמה). לא ניתן לשלב עם מגבלת יעד שאינו סקלר lvalue - כל ביטוי הוא יעד חוקי תחת /r.

  • g - גלובלי: מחליף כל התאמה לא־חופפת, לא רק את הראשונה.

  • c - מתקבל לסימטריה תחבירית עם m// אך אין לו השפעה התנהגותית על s///; מפעיל אזהרה תחת use warnings.

דגלי צד התאמה בשורה אחת: m (multiline ^/$), s (. מתאים לשורה חדשה), i (ללא רגישות לאותיות גדולות וקטנות), x / xx (רווחים מורחבים, הערות), p (שימור משתני התאמה; מיושן מאז 5.20), o (הידור תבנית פעם אחת), d / u / a / l (סמנטיקת ערכת תווים), n (לא לוכד בברירת מחדל). ראו את פרק המתאמים.

מתחמים#

כל תו שאינו רווח לבן עשוי להחליף את /. אם המתחם הנבחר הוא אחד מ־(, [, {, או <, האופרטור לוקח שתי קבוצות בסוגריים ומתחם ביניהן אופציונלי:

s(foo)(bar)
s{foo}{bar}
s<foo>/bar/
s[foo]{bar}g

מתחמי גרש יחיד מכבים אינטרפולציה הן ב־PATTERN והן ב־REPLACEMENT (אלא אם /e בתוקף, אשר תמיד מנתח את REPLACEMENT כקוד):

s'$name'$value';    # literal $name → literal $value, no interpolation

Backticks הם מתחמים רגילים; s`x`y` אינו מריץ פקודת shell.

כאשר המתחם הוא תו שהוא גם תו מזהה, נדרש רווח אחרי ה־s כך שהמנתח לא יקרא אותו כחלק משם האופרטור.

דוגמאות#

החלפה בסיסית במקום על $_:

$_ = 'the quick brown fox';
s/quick/slow/;                  # $_ is now 'the slow brown fox'

יעד מפורש עם =~:

my $path = '/usr/bin/perl';
$path =~ s|/usr/bin|/usr/local/bin|;
# $path is '/usr/local/bin/perl'

החלפה גלובלית, לכידת הספירה:

my $text = 'one two two three two';
my $n = ($text =~ s/two/2/g);   # $text: 'one 2 2 three 2'; $n == 3

/r לא הרסני - משאיר את המקור בשקט, מחזיר את העותק. ניבי ב־map:

my @clean = map { s/\s+\z//r } @lines;   # @lines untouched

הערכת קוד עם /e. הצד הימני הוא ביטוי Perl שערכו הופך להחלפה:

my $s = 'abc123xyz';
$s =~ s/\d+/$& * 2/e;           # $s is 'abc246xyz'

my %percent = (n => "\n", t => "\t");
$s =~ s/%(.)/$percent{$1} || $&/ge;     # expand %-escapes

/r משורשר - טרנספורמציות פונקציונליות טהורות ללא משתנה ביניים:

my $out = $text =~ s/foo/bar/r
                =~ s/baz/qux/r;

קבוצות לכידה והפניות לאחור בהחלפה - יש לשים לב לצורה $1, לא \1:

# swap the first two whitespace-separated fields
s/(\S+)\s+(\S+)/$2 $1/;

הניב 1 while עבור החלפות היוצרות התאמות חדשות:

# insert commas into an integer from the right
my $n = '1234567890';
1 while $n =~ s/(\d)(\d\d\d)(?!\d)/$1,$2/;
# $n is '1,234,567,890'

מקרי קצה#

  • היעד חייב להיות סקלר lvalue (אלא אם /r): משתנה, איבר, או substr lvalue. s/x/y/ כנגד מחרוזת מילולית או תוצאת קריאת פונקציה היא שגיאת זמן הידור. תחת /r כל ביטוי הוא משחק הוגן מכיוון ששום דבר אינו משונה.

  • תבנית ריקה משתמשת מחדש בהתאמה המוצלחת האחרונה. s//new/ מחליף כנגד מה ש־PATTERN התאים אליו לאחרונה בתיחום העוטף. נוח בתוך while (m/.../g) { s//x/ }, מפתיע כשקוד לא־קשור רץ בינתיים.

  • אינטרפולציה מתרחשת בזמן ריצה. s/$foo/$bar/ מהדר את התבנית מחדש בכל קריאה אם $foo משתנה. יש להשתמש ב־/o להידור פעם אחת והקפאת הערך הנלכד - או להדר מראש עם qr, שהיא החלופה המודרנית.

  • /e מנתח את ההחלפה בזמן הידור אף על פי שהיא רצה בזמן ההתאמה. שגיאות תחביר עולות כשהסקריפט נטען, לא כשההחלפה מתבצעת. כל e נוסף עוטף עוד eval סביב הערך.

  • /g עם התאמה ריקה מתקדם בתו אחד כדי להימנע מלולאה אינסופית: s/\b/-/g מכניס בין כל אסימון, הוא אינו תקוע במיקום הראשון.

  • !~ הופך את ההחזרה, לא את העבודה. $x !~ s/A/a/g עדיין משנה את $x; הוא רק מחזיר אמת כשלא נמצא A.

  • התאמת מתחם עבור סוגריים משתמשת בסוגר הסוגר המראתי: s{pat}{rep}, s<pat><rep>. מתחם שאינו סוגריים חייב להופיע שלוש פעמים בסך הכל: s/pat/rep/.

  • /c הוא no-op ב־s///. מתקבל לסימטריית מנתח עם m//; שימוש בו מייצר אזהרה תחת use warnings ולא יותר.

  • ניב השמה־כיעד. ($copy = $src) =~ s/x/y/g מאכלס את $copy בערך המשונה ומשאיר את $src בשקט. קוד מודרני מעדיף my $copy = $src =~ s/x/y/gr.

  • יעדים מקושרים או עם overloading. ללא /r, STORE מופעל אחרי ההחלפה כדי לכתוב את הערך החדש בחזרה; הערך שנשלף מועתק ל־buffer רגיל לפני שהתבנית מוחלת. עם /r התוצאה היא תמיד מחרוזת רגילה - tie / overloading אינם נשמרים בהחזרה.

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

תואם במלואו ל־Perl 5.42 במקור.

ראו גם#

  • m// - אופרטור ההתאמה; חולק את סמנטיקת דגלי צד ההתאמה ואת חוקי החזרה־מול־הקשר

  • tr/// - תעתוק תו־אחר־תו; מהיר בהרבה כשהמשימה היא תרגום תווים מילולי, לא regex

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

  • split - כשהמטרה היא לשבור מחרוזת על תבנית במקום להחליף התאמות, יש לפנות ל־split במקום זאת

  • Substitution chapter

    • the chapter dedicated to s///; covers /e, /r, /g, \K, and zero-length-match handling

  • Regular expressions guide

    • the full pattern-language reference; every match-side flag on s/// is defined there

  • $& - הטקסט המותאם, זמין בתוך ה־REPLACEMENT של כל s///