Βαθμωτά και συμβολοσειρές

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, ταιριάζοντες-πριν-το-squashing. Η τιμή επιστροφής είναι ακέραιος και συνήθως χρησιμοποιείται για να μετρά χαρακτήρες χωρίς να αλλάζει τίποτα (δείτε τον ιδιωματισμό tr/*/*/ παρακάτω).

Με /r, η tr αφήνει την αρχική συμβολοσειρά ως έχει, κατασκευάζει μεταγραμματισμένο αντίγραφο, και επιστρέφει αυτό το αντίγραφο. Η επιστρεφόμενη συμβολοσειρά είναι πάντα απλή συμβολοσειρά - ακόμη και αν ο στόχος ήταν tied μεταβλητή ή blessed αντικείμενο.

Στόχος χωρίς =~: η tr λειτουργεί στο $_. Στόχος με =~: η αριστερή πλευρά πρέπει να είναι lvalue (βαθμωτό, στοιχείο πίνακα, στοιχείο hash) εκτός αν χρησιμοποιηθεί /r, οπότε λειτουργεί οποιαδήποτε έκφραση.

Τροποποιητές#

Οι τέσσερις σημαίες στο τέλος αλλάζουν τι κάνει η tr με κάθε χαρακτήρα που βλέπει. Μπορούν να συνδυαστούν:

  • c - συμπληρωματικό του SEARCHLIST. Το σύνολο των χαρακτήρων στους οποίους δρα γίνεται κάθε χαρακτήρας που ΔΕΝ ανήκει στο SEARCHLIST. Υπό /c, το SEARCHLIST ταξινομείται κατά codepoint μετά τη συμπλήρωση, και οποιοδήποτε REPLACEMENTLIST εφαρμόζεται σε αυτό το ταξινομημένο σύνολο - οπότε η σειρά των χαρακτήρων που γράψατε στο SEARCHLIST δεν έχει πλέον σημασία.

  • d - διαγραφή. Χαρακτήρες που ταιριάζουν με το SEARCHLIST και δεν έχουν θέση στο REPLACEMENTLIST αφαιρούνται εντελώς από τον στόχο αντί να αντικατασταθούν με τον τελικό χαρακτήρα αντικατάστασης.

  • s - squash. Μια ακολουθία χαρακτήρων που μεταφράζονται όλοι στον ίδιο χαρακτήρα εξόδου συμπτύσσεται σε μία μοναδική εμφάνιση αυτής της εξόδου.

  • 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 από τον στόχο.

Εύρη χαρακτήρων#

Ένα ενωτικό μεταξύ δύο χαρακτήρων ορίζει συμπεριληπτικό εύρος codepoint: το 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"

Squash ακολουθιών με /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 "

Αφαίρεση του πιο σημαντικού bit από κάθε byte:

$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 επιστρέφει πάντα απλή συμβολοσειρά. Αν ο στόχος είναι tied βαθμωτό ή blessed αντικείμενο υπερφορτωμένο για συμβολοσειρές, το /r αφαιρεί τη μαγεία και σας δίνει μια φρέσκια απλή συμβολοσειρά.

  • Η tr δεν είναι η tr(1) του κελύφους. Παρόμοια σύνταξη, επικαλυπτόμενη σημασιολογία, αλλά η πτύχωση πεζών-κεφαλαίων πέρα από το ASCII ανήκει στις lc / uc / lcfirst / ucfirst ή στο s/// με \U / \L - όχι στην tr.

  • Το /c με REPLACEMENTLIST πολλαπλών χαρακτήρων δεν είναι φορητό μεταξύ συνόλων χαρακτήρων. Υπό /c το σύνολο αναζήτησης ταξινομείται κατά codepoint, και αυτή η σειρά ταξινόμησης διαφέρει μεταξύ ASCII και EBCDIC. Μείνετε σε REPLACEMENTLIST ενός χαρακτήρα όταν συνδυάζετε με /c, ή χρησιμοποιήστε το /c μόνο με /d (όπου η αντικατάσταση δεν παίζει ρόλο).

Διαφορές από το upstream#

Πλήρως συμβατό με το upstream Perl 5.42.

Δείτε επίσης#

  • y/// - συνώνυμο συμβατότητας με sed για το tr///· πανομοιότυπη συμπεριφορά, επιλέξτε όποιο διαβάζεται καλύτερα στα συμφραζόμενα

  • s/// - πλήρης αντικατάσταση regex· καταφύγετε σε αυτό όταν χρειάζεστε μοτίβα, συλλήψεις, ή παρεμβολή μεταβλητών στην πλευρά αναζήτησης

  • lc - μετατροπή σε πεζά με γνώση Unicode· χρησιμοποιήστε αντί για tr/A-Z/a-z/ όταν η είσοδος μπορεί να περιέχει μη-ASCII γράμματα

  • uc - μετατροπή σε κεφαλαία με γνώση Unicode· συμπλήρωμα της lc

  • tr στο perlop - η αναφορά του upstream για τη μορφή τελεστή τύπου εισαγωγικών, τους κανόνες οριοθετών, και τη φορητότητα εύρους

  • $_ - προεπιλεγμένος στόχος όταν η tr χρησιμοποιείται χωρίς =~ ή !~