Λίστες · Δεδομένα σταθερού μήκους
unpack#
Εξάγει τυποποιημένες τιμές από δυαδική συμβολοσειρά ή συμβολοσειρά σταθερού πλάτους σύμφωνα με ένα πρότυπο.
Η unpack είναι το αντίστροφο της pack. Διασχίζει την EXPR από αριστερά προς τα δεξιά, καταναλώνοντας τα bytes που περιγράφει κάθε οδηγία στο TEMPLATE και μετατρέποντάς τα σε τιμές Perl. Το αποτέλεσμα είναι λίστα - μία τιμή ανά οδηγία, ή ανά επανάληψη όταν η οδηγία έχει μετρητή. Αν παραλειφθεί η EXPR, η unpack διαβάζει από την $_.
Αυτή η σελίδα είναι μια αναφορά οδηγιών. Για αφηγηματική εισαγωγή με λυμένα παραδείγματα πρωτοκόλλων και μορφών αρχείων, ξεκινήστε από τον οδηγό pack/unpack.
Σύνοψη#
unpack TEMPLATE, EXPR
unpack TEMPLATE # reads from $_
my @fields = unpack "A10 A10 A*", $line;
my ($ver, $len, $payload) = unpack "n N A*", $msg;
Τι επιστρέφεται#
Μια λίστα τιμών, μία ανά οδηγία (ή ανά επανάληψη όταν η οδηγία έχει μετρητή). Σε βαθμωτό περιβάλλον, επιστρέφεται μόνο η πρώτη τιμή που παράχθηκε:
my @all = unpack "A4 A4 A*", $rec; # three values
my $first = unpack "A4 A4 A*", $rec; # just the first - not a count
Κάθε οδηγία καθορίζει τον τύπο Perl του αποτελέσματός της - δείτε τη στήλη «Τύπος αποτελέσματος» στον πίνακα οδηγιών παρακάτω.
Καθολική κατάσταση που επηρεάζει#
Το unpack TEMPLATE χωρίς EXPR διαβάζει την $_. Καμία άλλη καθολική του διερμηνέα δεν συμβουλεύεται. Οι οδηγίες C0 / U0 αλλάζουν τοπικά εντός του προτύπου την ερμηνεία byte-έναντι-χαρακτήρα, αλλά δεν μεταβάλλουν κάποια εξωτερική κατάσταση.
Σύνταξη προτύπου#
Πανομοιότυπη με αυτή της pack: ακολουθία γραμμάτων-οδηγιών, προαιρετικά ακολουθούμενη από μετρητές επανάληψης N / * / […] και τροποποιητές ! / < / >. Οι παρενθέσεις σχηματίζουν ομάδες· το # εισάγει σχόλιο προτύπου. Δείτε την pack για τους πλήρεις κανόνες σύνταξης - αυτή η σελίδα καλύπτει μόνο τη σημασιολογία που είναι ειδική για την unpack.
Πίνακας οδηγιών#
Όλες οι οδηγίες της unpack σε ένα μέρος. Το W είναι το πλάτος σε bytes που καταναλώνεται από την είσοδο ανά παραγόμενο βαθμωτό.
Οδηγία | W | Προσημασμένο | Endian | Τύπος αποτελέσματος | Τροποποιητές | Σημειώσεις |
|---|---|---|---|---|---|---|
| μετρητής | - | - | συμβολοσειρά | - | Επιστρέφει τα bytes ανέγγιχτα |
| μετρητής | - | - | συμβολοσειρά | - | Αφαιρεί τους τελικούς λευκούς χαρακτήρες και τα |
| μετρητής | - | - | συμβολοσειρά | - | Επιστρέφει τα πάντα μέχρι το πρώτο |
| μετρητής/8 | - | - | συμβολοσειρά bits | - | Χαρακτήρες «0»/»1», LSB κάθε byte πρώτο |
| μετρητής/8 | - | - | συμβολοσειρά bits | - | Χαρακτήρες «0»/»1», MSB κάθε byte πρώτο |
| μετρητής/2 | - | - | δεκαεξαδική συμβολοσειρά | - | Χαρακτήρες |
| μετρητής/2 | - | - | δεκαεξαδική συμβολοσειρά | - | Χαρακτήρες |
| 1 | ναι | - | ακέραιος | - | Προσημασμένο char |
| 1 | όχι | - | ακέραιος | - | Μη προσημασμένο char |
| 1 | όχι | - | ακέραιος | - | Μη προσημασμένο char· αποδίδει σημείο κώδικα σε κατάσταση |
| 2 | ναι | native | ακέραιος |
|
|
| 2 | όχι | native | ακέραιος |
|
|
| 4 | ναι | native | ακέραιος |
|
|
| 4 | όχι | native | ακέραιος |
|
|
| native | ναι | native | ακέραιος |
|
|
| native | όχι | native | ακέραιος |
|
|
| 8 | ναι | native | ακέραιος |
| Απαιτεί Perl με 64-bit ακεραίους |
| 8 | όχι | native | ακέραιος |
| Απαιτεί Perl με 64-bit ακεραίους |
| 2 | όχι | big | ακέραιος |
| Σειρά δικτύου· |
| 4 | όχι | big | ακέραιος |
| Σειρά δικτύου· |
| 2 | όχι | little | ακέραιος |
| Σειρά «VAX»· |
| 4 | όχι | little | ακέραιος |
| Σειρά «VAX»· |
| μέγεθος IV | ναι | native | ακέραιος |
| Εσωτερική |
| μέγεθος UV | όχι | native | ακέραιος |
| Εσωτερική |
| 4 | - | native | αριθμός |
| IEEE 754 απλής ακρίβειας |
| 8 | - | native | αριθμός |
| IEEE 754 διπλής ακρίβειας |
| μέγεθος NV | - | native | αριθμός |
| Εσωτερικός float της Perl |
| ποικίλλει | - | native | αριθμός |
| Long double |
| μέγεθος ptr | - | native | συμβολοσειρά |
| Αποαναφέρει δείκτη σε συμβολοσειρά τερματισμένη με |
| μέγεθος ptr | - | native | συμβολοσειρά |
| Αποαναφέρει δείκτη· μετρητής = bytes προς ανάγνωση |
| ποικίλλει | - | - | συμβολοσειρά | - | Bytes αποκωδικοποιημένα με uudecode |
| ποικίλλει | - | - | ακέραιος | - | Αριθμός σημείου κώδικα Unicode |
| ποικίλλει | όχι | - | ακέραιος | - | Ακέραιος συμπιεσμένος κατά BER |
| 1 | - | - | (κανένας) |
| Παρακάμπτει ένα byte προς τα εμπρός· το |
| −1 | - | - | (κανένας) |
| Επιστροφή κατά ένα byte· το |
| απόλυτο | - | - | (κανένας) |
| Μετάβαση στη θέση N εντός της εσώτερης ομάδας |
| - | - | - | ακέραιος |
| Επιστρέφει την τρέχουσα θέση (σχετική με την αρχή της ομάδας / συμβολοσειράς) |
| - | - | - | - |
| Ομάδα: ο μετρητής επανάληψης και η endianness διαδίδονται προς τα μέσα |
| - | - | - | - | - | Δείτε «Φορτία με πρόθεμα μήκους» παρακάτω |
| ποικίλλει | - | - | ακέραιος | - | Πρόθεμα. Άθροισμα ελέγχου N-bit των τιμών της επόμενης οδηγίας |
Οι τροποποιητές έχουν την ίδια σημασία όπως στην pack: το ! επιλέγει native μεγέθη, σημασιολογία ευθυγράμμισης, προσήμανση για τα n / N / v / V, ή μετατοπίσεις σε bytes για τα @ / .· τα < / > εξαναγκάζουν endianness.
Διαφορές από την pack#
Το
aδεν αφαιρεί τίποτα (επιστρέφει τα bytes ωμά)· τοAαφαιρεί τους τελικούς λευκούς χαρακτήρες και τα NUL· τοZσταματά στο πρώτο NUL. Με τηνpackκαι τα τρία συμπληρώνουν· με τηνunpackκαι τα τρία αφαιρούν συμπλήρωση με διαφορετικό τρόπο.Το
xπαρακάμπτει προς τα εμπρός κατά W, τοXεπιστρέφει κατά W. ΤοXπριν την αρχή της συμβολοσειράς είναι μοιραίο σφάλμα.Το
/διαβάζει μετρητή από τα δεδομένα και τον εφαρμόζει στην επόμενη οδηγία:unpack("W/a", "\004Gurusamy") # ("Guru") unpack("a3/A A*", "007 Bond J ") # (" Bond", "J") unpack("n/a*", "\x00\x0chello, world") # ("hello, world")
Με την
packη μορφή είναι length-item/item και το μήκος υπολογίζεται από το μήκος της τιμής. Με τηνunpackη μορφή είναι/item (χωρίς length-item πριν) - η προηγούμενη ακέραια οδηγία παρέχει τον μετρητή.Το
%Nείναι αποκλειστικό της unpack. Αντικαθιστά την κανονική έξοδο της επόμενης οδηγίας με το άθροισμαN-bit των τιμών που θα είχε αλλιώς παραγάγει αυτή η οδηγία. Το%32W*είναι το άθροισμα ελέγχουsumτου System V. Το%32b*μετρά τα ενεργοποιημένα bits.Το
.επιστρέφει την τρέχουσα θέση byte αντί να συμπληρώνει με μηδενικά μέχρι μία. Χρήσιμο μετά από πλοήγησηx/Xγια να μάθετε πού βρίσκεστε.Τα
pκαιPαποαναφέρουν δείκτες που διαβάζονται από την είσοδο - σχεδόν πάντα μη ασφαλές εκτός αν γνωρίζετε ότι η είσοδος παράχθηκε απόpack "p"/pack "P"στην ίδια διεργασία.Συμπεριφορά under-run / over-run: αν το πρότυπο ζητά περισσότερα δεδομένα από όσα περιέχει η
EXPR, το αποτέλεσμα δεν είναι καλά ορισμένο (μπορεί να αποδώσει κενές συμβολοσειρές, μηδενικά, μειωμένο μετρητή επανάληψης, ή εξαίρεση). Αν ηEXPRείναι μακρύτερη από όσο καταναλώνει το πρότυπο, τα τελικά bytes αγνοούνται σιωπηλά.
Παραδείγματα#
Ανάλυση μιας ελάχιστης κεφαλίδας δυαδικού πρωτοκόλλου - έκδοση 16-bit, μήκος 32-bit, στη συνέχεια φορτίο μεταβλητού μήκους, όλα σε σειρά bytes δικτύου:
my ($ver, $len, $payload) = unpack "n N A*", $msg;
Διαχωρισμός εγγραφής κειμένου σταθερού πλάτους - γρηγορότερος και πιο καθαρός από αλυσιδωμένες κλήσεις substr:
my ($date, $desc, $amount) = unpack "A10 A27 A*", $line;
# "2026-04-22 coffee at the station 3.50"
# $date = "2026-04-22", $desc = "coffee at the station",
# $amount = "3.50"
Εξαγωγή αθροίσματος ελέγχου τύπου System V με το πρόθεμα % - το 32-bit άθροισμα κάθε byte, μασκαρισμένο σε 16 bits:
my $checksum = do {
local $/; # slurp
unpack "%32W*", readline $fh;
} % 65535;
Μέτρηση ενεργοποιημένων bits σε διάνυσμα bits - το %32b* διαβάζει ολόκληρη τη μάσκα ως bits και επιστρέφει το άθροισμά τους:
my $setbits = unpack "%32b*", $selectmask;
Ανάγνωση ακολουθίας little-endian 32-bit ακεραίων από ωμό ενταμιευτή:
my @ints = unpack "V*", $buf;
Χρησιμοποιήστε το x για να παρακάμψετε bytes πλήρωσης, το X για να επιστρέψετε μετά από peek:
# 2-byte tag, skip 2 reserved bytes, then 4 32-bit big-endian values
my ($tag, @vals) = unpack "n x2 N4", $frame;
Οριακές περιπτώσεις#
Το βαθμωτό περιβάλλον επιστρέφει μόνο την πρώτη τιμή. Η ανάθεση της
unpackσε βαθμωτό σχεδόν ποτέ δεν είναι αυτό που θέλετε. Για να μετρήσετε πεδία, αναθέστε πρώτα σε λίστα, ή χρησιμοποιήστε() = unpack ...σε περιβάλλον λίστας:my $n = () = unpack "A10 A10 A*", $line; # 3
Το
*είναι άπληστο, όχι placeholder. ΤοA*καταναλώνει όλα τα υπόλοιπα bytes ως μία συμβολοσειρά· δεν υπάρχει οπισθοχώρηση. Μια οδηγία*πρέπει να είναι η τελευταία στην ακολουθία της, διαφορετικά τίποτα μετά από αυτή δεν εκτελείται.Τα πρότυπα δεν είναι κανονικές εκφράσεις. Οι λευκοί χαρακτήρες αγνοούνται, αλλά δεν υπάρχει εναλλαγή, ούτε
|, ούτε lookahead. Αν το σχήμα των δεδομένων εξαρτάται από προηγούμενα πεδία, κάντε unpack σε στάδια: αποκωδικοποιήστε μια κεφαλίδα, μετά καλέστε ξανά τηνunpackπάνω στο φορτίο χρησιμοποιώντας πρότυπο παραγόμενο από αυτό που μόλις διαβάσατε.Σημασιολογία byte έναντι χαρακτήρα. Η
unpackτρέχει σε κατάσταση byte προεπιλεγμένα πάνω σε συμβολοσειρά bytes, και σε κατάσταση χαρακτήρα σε συμβολοσειρά με σημαία UTF-8 τεθειμένη. ΤοC0εξαναγκάζει σε κατάσταση byte από εκείνο το σημείο· τοU0εξαναγκάζει σε κατάσταση UTF-8. Η ανάμειξη συμβολοσειράς σημαδεμένης ως UTF-8 με αριθμητικές οδηγίες όπωςNδιαβάζει σημεία κώδικα, όχι bytes - συνήθως όχι αυτό που θέλετε. Καλέστε πρώτα τηνutf8::encode, ή λειτουργήστε πάνω σε δεδομένα επιπέδου byte.Το
Xπριν την αρχή της συμβολοσειράς είναι μοιραίο.Τα
p/Pσε αυθαίρετη είσοδο αποτελούν απροσδιόριστη συμπεριφορά. Μην τα χρησιμοποιείτε ποτέ σε δεδομένα που δεν έχετε πακετάρει εσείς οι ίδιοι στην ίδια διεργασία.Χωρίς όρισμα
EXPR: τοunpack TEMPLATEδιαβάζει την$_. Χρήσιμο μέσα σε βρόχουςwhile (<$fh>) { ... }πάνω από εγγραφές σταθερού πλάτους.
Διαφορές από το upstream#
Πλήρως συμβατό με το upstream Perl 5.42.
Δείτε επίσης#
pack- η αντίστροφη λειτουργία· ίδια γλώσσα προτύπωνsubstr- εξαγωγή μίας σταθερής τομής· απλούστερη για ένα πεδίο, βραδύτερη για πολλάsprintf- πλήρης κύκλος μεταξύ δυαδικού και αναγνώσιμου από άνθρωποread- διαβάζει ωμά bytes από filehandle σε ενταμιευτή για τηνunpackvec- προσπελάσιμη κατά δείκτη πρόσβαση σε διάνυσμα bits χωρίς πρότυποΟδηγός pack/unpack - προσανατολισμένη σε εργασίες περιδιάβαση με λυμένα παραδείγματα πρωτοκόλλων και μορφών αρχείων