Συνταγές#
Τα εννοιολογικά κεφάλαια καλύπτουν την πειθαρχία· αυτή η σελίδα είναι το παράρτημα γρήγορης αναφοράς. Κάθε συνταγή είναι μια σύντομη, αυτοτελής απάντηση σε μια συνηθισμένη εργασία Unicode - το είδος του πράγματος για το οποίο το κλασικό βιβλίο συνταγών Unicode της Perl καταφεύγει σε ένα άρθρωμα CPAN, αλλά που οι ενσωματωμένες συναρτήσεις και η μηχανή regex της pperl χειρίζονται απευθείας.
Κάθε παράδειγμα εδώ υποθέτει ότι οι συμβολοσειρές σας είναι ήδη κείμενο - αποκωδικοποιημένες κατά την είσοδο, όπως περιγράφει το κεφάλαιο Συμβολοσειρές και κωδικοποιήσεις. Όλες οι παρακάτω λειτουργίες μιλούν χαρακτήρες, οπότε μια binary συμβολοσειρά που τους δοθεί θα μετρήσει bytes και θα σας εκπλήξει.
Ταξινόμηση και σύγκριση χωρίς διάκριση πεζών-κεφαλαίων με fc#
Η ενσωματωμένη συνάρτηση fc επιστρέφει το foldcase μιας συμβολοσειράς - την ίδια αναδίπλωση πεζών-κεφαλαίων Unicode που χρησιμοποιεί ο τροποποιητής μοτίβου /i. Δύο συμβολοσειρές είναι ίσες υπό αναδίπλωση πεζών-κεφαλαίων ακριβώς όταν η fc επιστρέφει το ίδιο αποτέλεσμα και για τις δύο, κάτι που κάνει την fc το σωστό εργαλείο για ταξινόμηση και σύγκριση χωρίς διάκριση πεζών-κεφαλαίων.
use v5.36; # or: use feature 'fc';
use utf8;
# sort case-insensitively
my @sorted = sort { fc($a) cmp fc($b) } @list;
# both are true:
fc("tschüß") eq fc("TSCHÜSS");
fc("Σίσυφος") eq fc("ΣΊΣΥΦΟΣ");
Η αναδίπλωση χειρίζεται τις περιπτώσεις που η απλή lc δεν μπορεί: το γερμανικό sharp s αναδιπλώνεται σε ss, και το ελληνικό τελικό σίγμα ς αναδιπλώνεται μαζί με το μεσαίο σ. Καταφύγετε στην fc αντί στην lc όποτε η σύγκριση πρέπει να αγνοεί την περίπτωση πεζών-κεφαλαίων με την πλήρη έννοια του Unicode.
Αυτό είναι μόνο αναδίπλωση πεζών-κεφαλαίων. Δεν αγνοεί τους τόνους, και δεν επιβάλλει την αλφαβητική σειρά ενός locale - για αυτό θα χρειαζόσασταν μια βιβλιοθήκη συνταξιοθεσίας όπως το Unicode::Collate, που δεν είναι ακόμη χρησιμοποιήσιμο στην pperl (δείτε το τέλος αυτής της σελίδας).
Κανονικοποίηση αλλαγών γραμμής με \R#
Το \R ταιριάζει μία μεμονωμένη αλλαγή γραμμής Unicode: το γράφημα CRLF δύο χαρακτήρων, ή οποιονδήποτε από τους κατακόρυφους λευκούς χαρακτήρες (LF, CR, form feed, vertical tab, next line, line separator, paragraph separator). Είναι ο φορητός τρόπος για να χειριστείτε αρχεία κειμένου που φτάνουν από διαφορετικά λειτουργικά συστήματα.
my $text = "line one\r\nline two\rline three\n";
$text =~ s/\R/\n/g; # normalise every linebreak to \n
Μετά την αντικατάσταση, το $text χρησιμοποιεί ένα μεμονωμένο \n παντού ανεξάρτητα από το πώς η είσοδος κωδικοποίησε τους τερματισμούς γραμμής της. Χρησιμοποιήστε το \R στη θέση μιας ρητής εναλλαγής \r?\n: καλύπτει τις περιπτώσεις που το χειρόγραφο μοτίβο ξεχνά.
Αντιστοίχιση μιας συστάδας γραφημάτων με \X#
Ένας ορατός στον χρήστη χαρακτήρας - ένα βασικό γράμμα μαζί με τυχόν συνδυαστικά σημάδια - είναι μια συστάδα γραφημάτων. Ο μετα-χαρακτήρας . ταιριάζει ένα σημείο κώδικα, που μπορεί να είναι μόνο μέρος μιας τέτοιας συστάδας· το \X ταιριάζει μια ολόκληρη συστάδα γραφημάτων.
use utf8;
# "é" written as e + COMBINING ACUTE ACCENT is two code points,
# but one grapheme.
my $str = "cafe\x{301}"; # c a f e + combining acute
$str =~ /^.{5}$/; # matches - five code points
$str =~ /^\X{4}$/; # matches - four graphemes
# find a vowel plus any combining diacritics
$str =~ / (?=[aeiou]) \X /xi;
Το \X είναι η σωστή μονάδα όποτε ο «χαρακτήρας» σημαίνει «αυτό που βλέπει ο αναγνώστης» αντί «σημείο κώδικα». Οι παρακάτω συνταγές χτίζουν πάνω του.
Τα πρώτα N γραφήματα, αντιστροφή, και μήκος ανά γράφημα#
Και οι τρεις αυτές εργασίες ανάγονται στην εφαρμογή του \X αντί για δεικτοδότηση ανά σημείο κώδικα. Λειτουργούν σωστά ανεξάρτητα από τη μορφή κανονικοποίησης στην οποία βρίσκεται η συμβολοσειρά.
Πάρτε τα πρώτα πέντε γραφήματα:
my ($first_five) = $str =~ /^ ( \X{5} ) /x;
Αντιστρέψτε μια συμβολοσειρά ανά γράφημα. Η αντιστροφή ανά σημείο κώδικα θα αποσπούσε ένα συνδυαστικό σημάδι από το βασικό του γράμμα και θα κατέστρεφε το κείμενο· η συλλογή των γραφημάτων πρώτα διατηρεί κάθε συστάδα ακέραιη:
$str = join "", reverse $str =~ /\X/g;
Μετρήστε το μήκος μιας συμβολοσειράς σε γραφήματα. Η λέξη brûlée είναι έξι γραφήματα αλλά μπορεί να φτάνει τα οκτώ σημεία κώδικα, οπότε η length και μια μέτρηση γραφημάτων μπορεί να διαφέρουν:
my $count = 0;
$count++ while $str =~ /\X/g;
Λεπτομερής ρύθμιση των προειδοποιήσεων UTF-8#
Η Perl χωρίζει τις προειδοποιήσεις UTF-8 σε τρεις υποκατηγορίες, ώστε να μπορείτε να σιγάσετε ένα είδος προειδοποίησης κακοσχηματισμένου Unicode χωρίς να σιγάσετε τις άλλες. Η pperl αναγνωρίζει και τα τρία ονόματα κατηγοριών:
no warnings "nonchar"; # the forbidden non-characters
no warnings "surrogate"; # UTF-16 surrogate code points
no warnings "non_unicode"; # code points above 0x10_FFFF
Απενεργοποιήστε μόνο την υποκατηγορία που έχετε σκόπιμο λόγο να επιτρέψετε - για παράδειγμα no warnings "non_unicode" σε κώδικα που χειρίζεται σημεία κώδικα πέρα από το εύρος Unicode επίτηδες - και αφήστε τις υπόλοιπες σε ισχύ ώστε γνήσια σφάλματα κωδικοποίησης να εξακολουθούν να εμφανίζονται.
Αποκωδικοποίηση του @ARGV#
Τα ορίσματα γραμμής εντολών φτάνουν ως bytes. Αν ένας χρήστης περάσει ένα μη-ASCII όρισμα, πρέπει να το αποκωδικοποιήσετε πριν το αντιμετωπίσετε ως κείμενο, ακριβώς όπως θα αποκωδικοποιούσατε οποιαδήποτε άλλη είσοδο. Η φορητή μορφή εφαρμόζει τη decode πάνω στο @ARGV:
use Encode qw(decode);
@ARGV = map { decode('UTF-8', $_, 1) } @ARGV;
Μετά από αυτή τη γραμμή, κάθε στοιχείο του @ARGV είναι μια συμβολοσειρά κειμένου και συμπεριφέρεται υπό την length, τη regex, και τις λειτουργίες πεζών-κεφαλαίων σε χαρακτήρες αντί για bytes. Το τρίτο όρισμα 1 (ο έλεγχος Encode::FB_CROAK) κάνει ένα κακοσχηματισμένο όρισμα μοιραίο σφάλμα αντί για σιωπηλή αντικατάσταση, κάτι που είναι συνήθως αυτό που θέλετε για είσοδο που δεν μπορείτε να ζητήσετε ξανά.
Προσαρμοσμένη ιδιότητα ανά εύρος σημείων κώδικα#
A \p{...} property can name a subroutine you define. When the regex engine meets an unknown property \p{In_Foo}, it calls In_Foo, which returns a list of code-point ranges (one START\tEND pair per line, in hexadecimal); the property then matches any character in those ranges.
sub In_Greek { return "0370\t03FF\n0780\t07BF\n" }
"\x{3b1}" =~ /\p{In_Greek}/; # matches - alpha is in 0370..03FF
Αυτός είναι ο φορητός τρόπος για να ορίσετε μια ad-hoc κλάση χαρακτήρων μία φορά και να την επαναχρησιμοποιήσετε με το όνομά της σε διάφορα μοτίβα, χωρίς να αναγράφετε το εύρος σε κάθε regex.
Αρθρώματα σε εκκρεμότητα στην pperl#
Μια χούφτα συνταγές στο κλασικό βιβλίο συνταγών Unicode της Perl καταφεύγουν στα βοηθητικά αρθρώματα Unicode που η Perl παρέχει ως μεταγλωττισμένες επεκτάσεις: Unicode::Normalize (κανονικοποίηση NFC, NFD, NFKC, NFKD), Unicode::Collate και Unicode::Collate::Locale (αλφαβητική και εξαρτώμενη από locale ταξινόμηση, σύγκριση χωρίς διάκριση τόνων), Unicode::GCString (substr με επίγνωση γραφημάτων και πλάτος στηλών εκτύπωσης), Unicode::UCD (προγραμματική αναζήτηση κατηγορίας χαρακτήρα και αριθμητικής τιμής), και Unicode::LineBreak (κοπή γραμμών σύμφωνα με τους κανόνες Unicode).
Αυτά τα αρθρώματα δεν είναι ακόμη διαθέσιμα στην pperl: η φόρτωση ενός σήμερα αποτυγχάνει με dynamic loading not available in this perl. Μέχρι να γίνουν, η οικογένεια regex \X παραπάνω καλύπτει το μήκος, την αντιστροφή και την εξαγωγή σταθερού πλήθους με επίγνωση γραφημάτων (αν και όχι το πλάτος στηλών εκτύπωσης), και δεν υπάρχει εδώ υποκατάστατο για την κανονικοποίηση ή τη συνταξιοθεσία locale. Οι ονομασμένοι χαρακτήρες και οι ιδιότητες ορισμένες από τον χρήστη, αντιθέτως, λειτουργούν σήμερα, όπως δείχνουν οι παραπάνω συνταγές.