# Συνταγές Τα εννοιολογικά κεφάλαια καλύπτουν την πειθαρχία· αυτή η σελίδα είναι το παράρτημα γρήγορης αναφοράς. Κάθε συνταγή είναι μια σύντομη, αυτοτελής απάντηση σε μια συνηθισμένη εργασία Unicode - το είδος του πράγματος για το οποίο το κλασικό βιβλίο συνταγών Unicode της Perl καταφεύγει σε ένα άρθρωμα CPAN, αλλά που οι ενσωματωμένες συναρτήσεις και η μηχανή regex της pperl χειρίζονται απευθείας. Κάθε παράδειγμα εδώ υποθέτει ότι οι συμβολοσειρές σας είναι ήδη κείμενο - αποκωδικοποιημένες κατά την είσοδο, όπως περιγράφει το κεφάλαιο [Συμβολοσειρές και κωδικοποιήσεις](strings-and-encodings.md). Όλες οι παρακάτω λειτουργίες μιλούν χαρακτήρες, οπότε μια binary συμβολοσειρά που τους δοθεί θα μετρήσει bytes και θα σας εκπλήξει. ## Ταξινόμηση και σύγκριση χωρίς διάκριση πεζών-κεφαλαίων με `fc` Η ενσωματωμένη συνάρτηση [`fc`](../../p5/core/perlfunc/fc.md) επιστρέφει το *foldcase* μιας συμβολοσειράς - την ίδια αναδίπλωση πεζών-κεφαλαίων Unicode που χρησιμοποιεί ο τροποποιητής μοτίβου `/i`. Δύο συμβολοσειρές είναι ίσες υπό αναδίπλωση πεζών-κεφαλαίων ακριβώς όταν η `fc` επιστρέφει το ίδιο αποτέλεσμα και για τις δύο, κάτι που κάνει την `fc` το σωστό εργαλείο για ταξινόμηση και σύγκριση χωρίς διάκριση πεζών-κεφαλαίων. ```perl 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`](../../p5/core/perlfunc/lc.md) δεν μπορεί: το γερμανικό 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). Είναι ο φορητός τρόπος για να χειριστείτε αρχεία κειμένου που φτάνουν από διαφορετικά λειτουργικά συστήματα. ```perl 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` ταιριάζει μια ολόκληρη συστάδα γραφημάτων. ```perl 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` αντί για δεικτοδότηση ανά σημείο κώδικα. Λειτουργούν σωστά ανεξάρτητα από τη μορφή κανονικοποίησης στην οποία βρίσκεται η συμβολοσειρά. Πάρτε τα πρώτα πέντε γραφήματα: ```perl my ($first_five) = $str =~ /^ ( \X{5} ) /x; ``` Αντιστρέψτε μια συμβολοσειρά ανά γράφημα. Η αντιστροφή ανά σημείο κώδικα θα αποσπούσε ένα συνδυαστικό σημάδι από το βασικό του γράμμα και θα κατέστρεφε το κείμενο· η συλλογή των γραφημάτων πρώτα διατηρεί κάθε συστάδα ακέραιη: ```perl $str = join "", reverse $str =~ /\X/g; ``` Μετρήστε το μήκος μιας συμβολοσειράς σε γραφήματα. Η λέξη `brûlée` είναι έξι γραφήματα αλλά μπορεί να φτάνει τα οκτώ σημεία κώδικα, οπότε η [`length`](../../p5/core/perlfunc/length.md) και μια μέτρηση γραφημάτων μπορεί να διαφέρουν: ```perl my $count = 0; $count++ while $str =~ /\X/g; ``` ## Λεπτομερής ρύθμιση των προειδοποιήσεων UTF-8 Η Perl χωρίζει τις προειδοποιήσεις UTF-8 σε τρεις υποκατηγορίες, ώστε να μπορείτε να σιγάσετε ένα είδος προειδοποίησης κακοσχηματισμένου Unicode χωρίς να σιγάσετε τις άλλες. Η pperl αναγνωρίζει και τα τρία ονόματα κατηγοριών: ```perl 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`: ```perl use Encode qw(decode); @ARGV = map { decode('UTF-8', $_, 1) } @ARGV; ``` Μετά από αυτή τη γραμμή, κάθε στοιχείο του `@ARGV` είναι μια συμβολοσειρά κειμένου και συμπεριφέρεται υπό την [`length`](../../p5/core/perlfunc/length.md), τη 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. ```perl 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. Οι ονομασμένοι χαρακτήρες και οι ιδιότητες ορισμένες από τον χρήστη, αντιθέτως, λειτουργούν σήμερα, όπως δείχνουν οι παραπάνω συνταγές.