סקלרים ומחרוזות

tr///#

החלפה תו־אחר־תו. tr סורק מחרוזת ומחליף כל הופעה של תו מ־SEARCHLIST בתו המתאים מבחינת מיקום מ־REPLACEMENTLIST, ומחזיר את ספירת התווים שבהם נגע.

זה לא regex. SEARCHLIST הוא קבוצה של תווים מילוליים (עם קיצור טווח כמו a-z), לא תבנית. אין מטה־תווים, אין \d, אין אינטרפולציית משתנים. טבלת התרגום נבנית פעם אחת, בזמן הידור.

תקציר#

tr/SEARCHLIST/REPLACEMENTLIST/cdsr
y/SEARCHLIST/REPLACEMENTLIST/cdsr
$str =~ tr/abc/xyz/;
$count = ($str =~ tr/aeiou//);

y/// הוא מילה נרדפת לתאימות sed עבור tr/// - התנהגות זהה, מתאמים זהים. ראו y///.

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

ללא המתאם /r, tr משנה את מחרוזת היעד במקום ומחזיר את מספר התווים שהותאמו - או, תחת /d, הותאמו־או־נמחקו; תחת /s, הותאמו־לפני־ריסוק. ערך ההחזרה הוא מספר שלם ובדרך כלל בשימוש כדי לספור תווים מבלי לשנות דבר (ראו הניב tr/*/*/ להלן).

עם /r, tr משאיר את המחרוזת המקורית בשקט, בונה עותק מתועתק, ומחזיר את העותק הזה. המחרוזת המוחזרת היא תמיד מחרוזת רגילה - אפילו אם היעד היה משתנה מקושר או עצם bless.

יעד ללא =~: tr פועל על $_. יעד עם =~: הצד השמאלי חייב להיות lvalue (סקלר, איבר מערך, איבר האש) אלא אם /r בשימוש, ובמקרה זה כל ביטוי עובד.

מתאמים#

ארבעת הדגלים הגוררים משנים מה tr עושה עם כל תו שהוא רואה. ניתן לשלב אותם:

  • c - משלים את SEARCHLIST. קבוצת התווים שעליה פועלים הופכת לכל תו שאינו ב־SEARCHLIST. תחת /c, SEARCHLIST ממוין לפי נקודת קוד לאחר השלמה, וכל REPLACEMENTLIST מוחל על אותה קבוצה ממוינת - כך שסדר התווים שכתבתם ב־SEARCHLIST כבר לא חשוב.

  • d - מחיקה. תווים שהותאמו על ידי SEARCHLIST שאין להם מיקום ב־REPLACEMENTLIST מוסרים מהיעד לחלוטין במקום להיות מוחלפים בתו ההחלפה הסופי.

  • s - ריסוק. רצף של תווים שכולם מתורגמים לאותו תו פלט מתכווץ למופע יחיד של אותו פלט.

  • r - החזרת עותק משונה. אל תיגע ביעד. החזרת המחרוזת המתועתקת במקום ספירה.

חוקי אורך רשימת ההחלפה#

הקשר בין SEARCHLIST ל־REPLACEMENTLIST משתנה עם המתאמים:

  • אם REPLACEMENTLIST קצר מ־SEARCHLIST ו־/d אינו בתוקף, תו ההחלפה הסופי משוכפל כדי למלא את הפער. tr/abcd/AB/ זהה ל־tr/abcd/ABBB/.

  • אם REPLACEMENTLIST קצר מ־SEARCHLIST וגם /d בתוקף, תווי SEARCHLIST עודפים נמחקים. tr/abcd/AB/d עושה tr/ab/AB/ בתוספת s/[cd]//g.

  • אם REPLACEMENTLIST ריק ו־/d אינו בתוקף, REPLACEMENTLIST הופך לעותק של SEARCHLIST. זוהי הצורה רק־לספירה: tr/abc// סופר a, b, c מבלי לשנות דבר.

  • אם REPLACEMENTLIST ריק וגם /d בתוקף, כל תו ב־SEARCHLIST נמחק. tr/abc//d מסיר את כל ה־a, b, c מהיעד.

טווחי תווים#

מקף בין שני תווים מציין טווח נקודות קוד מכליל: tr/A-J/0-9/ הוא tr/ABCDEFGHIJ/0123456789/. מקף בהתחלה, בסוף, או אחרי בקסלאש נלקח מילולית - tr/-ab-/xyz/ ו־tr/\-abc/wxyz/ מתייחסים למקף כתו המילולי -.

יש להשתמש רק בטווחי אלפבית ASCII (אותה רישה) או טווחי ספרות ASCII. a-z, A-Z, 0-9, ותת־קבוצות נקיות כמו h-k או B-E הם נישאים ומשמעם בדיוק מה שהם נקראים. טווחי מעורבי־רישה, טווחי \x, או טווחים החוצים את הגבול של אלפבית/ספרות נראים מובנים מאליהם אבל מייצרים תוצאות שונות בפלטפורמות לא־ASCII - יש לכתוב אותם במפורש.

טווחי Unicode נישאים משתמשים בנקודות קצה \N{U+...}:

$str =~ tr/\N{U+20}-\N{U+7E}//d;    # delete all ASCII printables

מתחמים#

שלושת המתחמים סביב SEARCHLIST ו־REPLACEMENTLIST יכולים להיות כל זוג תואם של תווים ניתנים להדפסה, לא רק /. זוגות סוגריים ({}, (), [], <>) דורשים שני זוגות עצמאיים, אחד לכל רשימה:

tr(aeiouy)(yuoiea);
tr[+\-*/]"ABCD";

כאשר המתחם הוא גרש יחיד (tr'...'...'), הרשימות מטופלות כמעט מילולית - רק זוגות \\ מתכווצים. מקפים בתוך tr בגרש יחיד אינם מציינים טווח; הם מקפים מילוליים.

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

  • $_ - יעד ברירת מחדל כשלא =~ ולא !~ בשימוש. tr/// לבדו קורא ו(אלא אם /r בשימוש) משנה את $_.

  • אין משתנים מיוחדים אחרים. tr אינו מגדיר את $&, $1, וכו« - אלה שייכים להתאמת regex, ו־tr אינו regex.

דוגמאות#

אותיות קטנות של ASCII לאותיות גדולות:

my $name = "Perl";
$name =~ tr/a-z/A-Z/;           # $name is now "PERL"

ספירה מבלי לשנות - הניב tr/X/X/. ההחלפה היא אותו תו, כך שהמחרוזת אינה משתנה; ערך ההחזרה הוא הספירה:

my $stars = "**hello**";
my $cnt   = ($stars =~ tr/*/*/);    # $cnt == 4

REPLACEMENTLIST ריק ללא /d סופר גם כן:

my $digits = ($text =~ tr/0-9//);   # count ASCII digits in $text

מחיקת תווים עם /d:

my $s = "(555) 123-4567";
$s =~ tr/0-9//cd;               # keep only digits: "5551234567"

ריסוק רצפים עם /s:

my $line = "hello    world";
$line =~ tr/ //s;               # "hello world"

/r לא הרסני - בניית עותק, השארת המקור:

my $host  = "example.com";
my $HOST  = $host =~ tr/a-z/A-Z/r;    # $host unchanged, $HOST uppercased

שרשור עם אופרטורי /r אחרים:

my $tag = $host =~ tr/a-z/A-Z/r
               =~ s/\./_/gr;     # "EXAMPLE_COM"

map עם /r - הפיכת רשימת מחרוזות לרשימה מטופלת:

my @upper = map tr/a-z/A-Z/r, @names;

דחיסת מילים שלמות - כיווץ רצפים לא־אלפביתיים לרווח יחיד:

$sentence =~ tr/a-zA-Z/ /cs;    # "foo, bar; BAZ!" -> "foo bar BAZ "

הסרת הביט הגבוה מכל בייט:

$bytes =~ tr[\200-\377][\000-\177];

מקרי קצה#

  • לא regex. tr/\d/X/ מתאים לתווים המילוליים \ ו־d, לא ”כל ספרה“. מחלקות תווים, עוגנים, מכמתים, והפניות לאחור - כולם מילוליים בשקט. אם רוצים regex, יש להשתמש ב־s///.

  • אין אינטרפולציית משתנים. $var ו־@var בתוך הרשימות הם $ / @ מילוליים בתוספת השם שאחריהם. הטבלה מהודרת פעם אחת, כשהתוכנית מנותחת. כדי לבנות את הרשימות דינמית, יש לעטוף ב־eval:

    eval "tr/$from/$to/";
    die $@ if $@;
    
  • תווים חוזרים ב־SEARCHLIST - רק המיפוי הראשון נספר. tr/AAA/XYZ/ מתרגם כל A ל־X; המיקומים Y ו־Z בלתי נגישים.

  • אין סריקה מחדש. פלט מתועתק אינו מוזן מחדש לטבלה, אפילו אם תו ההחלפה מופיע גם ב־SEARCHLIST. tr/ox/xo/ הופך את "oxxo" ל־"xoox", לא לאיזו נקודת שבת.

  • !~ עם tr - מחזיר 0 אם תו כלשהו שונה, 1 אחרת. שימושי רק לבדיקות מהירות ”כלום לא קרה“:

    $foo !~ tr/A/a/     # true iff no 'A' was in $foo
    
  • דרישת lvalue. ללא /r, יעד ה־=~ חייב להיות בר־השמה. "constant" =~ tr/a/b/ היא שגיאת זמן הידור.

  • /r תמיד מחזיר מחרוזת רגילה. אם היעד הוא סקלר מקושר או עצם bless עם overloading של מחרוזת, /r מסיר את הקסם ונותן לכם מחרוזת רגילה רעננה.

  • tr אינו tr(1) של ה־shell. תחביר דומה, סמנטיקה חופפת, אך קיפול אותיות מעבר ל־ASCII שייך ל־lc / uc / lcfirst / ucfirst או ל־s/// עם \U / \L - לא ל־tr.

  • /c עם REPLACEMENTLIST רב־תווים אינו נישא לרוחב ערכות תווים. תחת /c קבוצת החיפוש ממוינת לפי נקודת קוד, וסדר המיון הזה שונה בין ASCII ל־EBCDIC. יש להיצמד ל־REPLACEMENTLIST בעל תו יחיד בעת שילוב עם /c, או להשתמש ב־/c רק עם /d (שבו ההחלפה לא משנה).

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

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

ראו גם#

  • y/// - מילה נרדפת לתאימות sed עבור tr///; התנהגות זהה, יש לבחור באיזו שנקראת טוב יותר בהקשר

  • s/// - החלפת regex מלאה; יש לפנות אליה כשצריך תבניות, לכידות, או אינטרפולציית משתנים בצד החיפוש

  • lc - אותיות קטנות מודעות ל־Unicode; יש להשתמש במקום tr/A-Z/a-z/ כשהקלט עשוי להכיל אותיות לא־ASCII

  • uc - אותיות גדולות מודעות ל־Unicode; משלים ל־lc

  • tr ב־perlop - הפניית המקור עבור צורת האופרטור דמוי־ציטוט, חוקי מתחם, ונשיאות טווח

  • $_ - יעד ברירת מחדל כאשר tr בשימוש ללא =~ או !~