NOME |
perlunicode - Supporto Unicode in Perl
Un supporto completo Unicode richiede una gran quantità di lavoro. Sebbene Perl non implementi lo standard Unicode e i rapporti tecnici allegati da parte a parte, Perl fornisce comunque una gran quantità di funzionalità Unicode.
:utf8
. Altre codifiche possono essere convertite alla
codifica interna Perl in lettura (o viceversa in scrittura) usando lo
strato :encoding(...)
. Leggete the open manpage.
Per indicare che il sorgente stesso dello script è in una particolare codifica, usate the encoding manpage.
use utf8
è ancora necessario per usare UTF-8/UTF-EBCDIC negli scriptuse utf8
deve essere
inclusa esplicitamente per attivare il riconoscimento di stringhe in
UTF-8 nei sorgenti degli script (nelle costanti stringa e espressioni
regolari, o nei nomi degli identificatori) sulle macchine ASCII,
ovvero il riconoscimento di UTF-EBCDIC sulle macchine EBCDIC. <
Questi sono i soli casi in cui è necessario un esplicito use
utf8
>. Cfr. the utf8 manpage.
Potete anche usare la direttiva encoding
per cambiare la codifica
di default per i dati nei vostri script; cfr. the encoding manpage.
use encoding
è necessario per interpretare correttamente le stringhe di byte non Latin-1Se volete che le stringhe di byte siano interpretate come UTF-8, usate
la direttiva encoding
:
use encoding 'utf8';
Cfr. Semantica a byte e a caratteri per ulteriori dettagli.
A partire dalla versione 5.6, la rappresentazione interna delle stringhe in Perl è basata su caratteri ``larghi'' (nel senso che possono occupare più di un byte).
Nel futuro, si potrà supporre che le operazioni a livello di Perl lavorino su caratteri anziché byte.
Comunque, come misura di compatiblità temporanea, Perl cerca di fornire un percorso sicuro di migrazione per i vostri programmi da semantica a byte a semantica a caratteri. Nel caso di operazioni per le quali Perl può decidere senza ambiguità che i dati in ingresso sono caratteri, viene usata la semantica a caratteri. Nel caso di operazioni per le quali questa decisione non può essere effettuata senza ulteriori informazioni da parte dell'utente, Perl decide per la compatibilità e sceglie la semantica a byte.
Questo comportamento mantiene la compatiblità con versioni
precedenti del Perl, che usavano la semantica a byte solo nel caso in
cui nessuno degli input del programma erano indicati come sorgenti di
caratteri Unicode. Questi dati possono provenire da filehandle, da
chiamate a programmi esterni, da informazioni fornite dal sistema (ad
esempio %ENV
), o da costanti nel sorgente.
La direttiva bytes
forzerà sempre, indipendentemente dalla
piattaforma, la semantica a byte in un particolare scope
lessicale. Cfr. the bytes manpage.
La direttiva utf8
è principalmente un sistema di
compatibilità che attiva il riconoscimenti di costanti
UTF-(8|EBCDIC) da parte del parser. Notate che questa direttiva
è necessaria solo finché Perl assume una semantica a
byte; quando la semantica a caratteri diventerà quella
predefinita, questa direttiva potrà non avere più
effetto. Cfr. the utf8 manpage.
Tranne dove viene detto esplicitamente, gli operatori Perl usano la
semantica a carattere per i dati Unicode e la semantica a byte per i
dati non Unicode. La decisione di usare la semantica a carattere
è fatta in modo trasparente. Se i dati provengono da una
sorgente Unicode -- ad esempio, da un filehandle cui è stato
applicato uno strato di codifica, o da una costante Unicode nel
sorgente -- si applica la semantica a carattere. Altrimenti, si
applica la semantica a byte. La direttiva bytes
è usata per
forzare la semantica a byte sui dati Unicode.
Se si concatenano stringe con semantica a byte e stringhe Unicode, la
nuova stringa verrà creata decodificando la stringa di byte
usando ISO 8859-1 (Latin-1), anche se le stringhe Unicode usavano
EBCDIC. Questa trasformazione avviene senza considerare quale sia la
codifica nativa a 8 bit del sistema; per cambiare questo comportamento
in sistemi la cui codifica nativa non è né Latin-1
né EBCDIC usate la direttiva encoding
. Cfr. the encoding manpage.
Secondo la semantica a carattere, molte operazioni che prima lavoravano sui byte ora lavorano sui caratteri. Un carattere in Perl è, a livello logico, un numero tra 0 e circa 2**31. I caratteri con valore più alto potrebbero essere codificati internamente con sequenze di byte più lunghe, ma questi dettagli sono quasi del tutto nascosti al codice Perl. Leggete the perluniintro manpage per ulteriori informazioni.
La semantica a carattere ha gli effetti seguenti:
Se usate un editor Unicode per scrivere i vostri programmi, i caratteri Unicode possono essere inseriti direttamente nelle costanti stringa in una qualunque delle vari codifiche di Unicode (UTF-8, UTF-EBCDIC, UTF-16, etc.), ma verranno riconosciuti come tali e convertiti nella codifica interna del Perl solo se la codifica è stata indicata con un'apposita direttiva the encoding manpage.
Potete inserire caratteri Unicode all'interno di una stringa anche
usando la notazione \x{...}
. Tre le graffe dovete inserire il code
point Unicode del carattere, in esadecimale. Ad esempio, una faccina
sorridente è \x{263A}
. Questo metodo funziona soltanto per
i caratteri con valore maggiore o uguale a 0x100
.
Inoltre, se scrivete
use charnames ':full';
potete usare la notazione \N{...}
inserendo tre le graffe il nome
ufficiale Unicode del carattere, come ad esempio \N{WHITE SMILING FACE}
.
.
''
fa match su un carattere anziché su un byte. Il pattern ``\C
'' forza
il match di un singolo byte -- si chiama \C
perché un byte nel
linguaggio C viene chiamato char
.
Le classi di caratteri nelle espressioni regolari fanno match su
caratteri anziché byte e fanno match sulle proprietà
dei caratteri specificate nel database delle proprietà
Unicode. Ad esmepio, ``\w
'' può essere usato per far match su
un ideogramma giapponese.
(Comunque, a causa di una limitazione dell'implementazione attuale,
usare \w
o \W
all'interno di una classe di caratteri [...]
farà sempre match sui byte).
\p{}
``fa match
su proprietà'' e la sua negazione \P{}
.
Ad esempio, \p{Lu}
fa match con un qualsiasi carattere che abbia la
proprietà Unicode ``Lu'' (lettera maiuscola, da ``Letter,
uppercase''), mentre \p{M}
fa match su qualsiasi carattere con la
proprietà ``M'' (accenti e simili, da ``Mark''). Le graffe non
sono necessarie per proprietà di una sola lettera, per cui
\p{M}
è uguale a \pM
. Sono disponibili molte
proprietà predefinite, come ad esempio \p{Mirrored}
o
\p{Tibetan}
.
I nomi ufficiali Unicode di script e blocchi usano spazi e trattini
come separatori, ma per comodità potete usare trattini, spazi,
o sottolineature, e non vengono distinte maiuscola da minuscole. Si
suggerisce, comunque, che per coerenza usiate la seguente convenzione:
usate il nome ufficiale Unicode per lo script, la proprietà, o
il blocco (ma leggete sotto per le regole aggiuntive che si applicano
ai nomi di blocco), tolti spazi e trattini, con ciascuna parola avente
la sola prima lettera maiuscola. Così Latin-1 Supplement
diventa Latin1Supplement
.
Potete anche usare la negazione, sia in \p{}
che in \P{}
inserendo un circonflesso (^
) tra la graffa aperta e il nome della
proprietà: \p{^Tamil}
è equivalente a \P{Tamil}
.
NOTA: Le proprietà, script e blocchi elencati qui di seguito sono quelli di Unicode 3.2.0, Marzo 2002, ovvero Perl 5.8.0, Luglio 2002. Unicode 4.0.0 è uscito in Aprile 2003, e Perl 5.8.1 in Settembre 2003. >
Quelle che seguono sono le proprietà base della categoria ``generale''
di Unicode, assieme alla loro forma estesa (e a una traduzione, NdT).
Potete usare l'una o l'altra; ad esempio, \p{Lu}
e
\p{LowercaseLetter}
sono identici.
Breve Estesa Traduzione
L Letter lettera LC CasedLetter lettera con versioni maiuscola, minuscola, etc. Lu UppercaseLetter lettera maiuscola Ll LowercaseLetter lettera minuscola Lt TitlecaseLetter lettera da titolo Lm ModifierLetter lettera modificatrice Lo OtherLetter altra lettera
M Mark diacritico Mn NonspacingMark diacritico senza larghezza Mc SpacingMark diacritico con larghezza Me EnclosingMark diacritico circoscritto
N Number cifra Nd DecimalNumber cifra decimale Nl LetterNumber cifra lettera No OtherNumber altra cifra
P Punctuation punteggiatura Pc ConnectorPunctuation punteggiatura legante Pd DashPunctuation punteggiatura tratto Ps OpenPunctuation punteggiatura di apertura Pe ClosePunctuation punteggiatura di chiusura Pi InitialPunctuation punteggiatura iniziale (puo` comportarsi come Ps o Pe a seconda dell'uso) Pf FinalPunctuation punteggiatura finale (puo` comportarsi come Ps o Pe a seconda dell'uso) Po OtherPunctuation altra punteggiatura
S Symbol simbolo Sm MathSymbol simbolo matematico Sc CurrencySymbol simbolo di valuta Sk ModifierSymbol simbolo modificatore So OtherSymbol altro simbolo
Z Separator separatore Zs SpaceSeparator separatore spazio Zl LineSeparator separatore linea Zp ParagraphSeparator separatore paragrafo
C Other altro Cc Control controllo Cf Format formato Cs Surrogate surrogato (non usabile) Co PrivateUse uso privato Cn Unassigned non assegnato
Proprietà di una sola lettera fanno match con caratteri che
abbiano una qualsiasi delle proprietà di due lettere che
cominciano con essa. LC
e L&
sono casi speciali: indicano
l'unione di Ll
, Lu
e Lt
.
Poiché Perl evita all'utente di dover comprendere la
rappresentazione interna dei caratteri Unicode, non c'è
bisogno di implementare il concetto piuttosto scomodo dei
surrogati. Perciò Cs
non è supportata.
Poiché gli script differiscono nella loro direzionalità -- l'ebraico è scritto da destra a sinistra, ad esempio -- Unicode fornisce le seguenti proprietà nella classe BidiClass:
Proprieta` Significato
L Sinistra-Destra LRE Sinistra-Destra Immerso LRO Sinistra-Destra Forzato R Destra-Sinistra AL Destra-Sinistra Arabo RLE Destra-Sinistra Immerso RLO Destra-Sinistra Forzato PDF Estrai formato direzionale EN Numero Europeo ES Separatore di Numero Europeo ET Terminatore di Numero Europeo AN Numero Arabo CS Separatore Comune di Numero NSM Diacritico senza larghezza BN Ininfluente al bordo B Separatore di Paragrafo S Separatore di Segmento WS Spazio ON Altri ininfluenti
Ad esempio, \p{BidiClass:R}
fa match sui caratteri che sono normalmente
scritti da destra a sinistra.
I nomi degli script che possono essere usati con \p{...}
e
\P{...}
, come ad esempio \p{Latin}
o \p{Cyrillic}
, sono i
seguenti:
Arabic Armenian Bengali Bopomofo Buhid CanadianAboriginal Cherokee Cyrillic Deseret Devanagari Ethiopic Georgian Gothic Greek Gujarati Gurmukhi Han Hangul Hanunoo Hebrew Hiragana Inherited Kannada Katakana Khmer Lao Latin Malayalam Mongolian Myanmar Ogham OldItalic Oriya Runic Sinhala Syriac Tagalog Tagbanwa Tamil Telugu Thaana Thai Tibetan Yi
Classi di proprietà estese possono aggiungersi a quelle base, definite nel database Unicode PropList (con spiegazione in italiano, NdT):
ASCIIHexDigit cifra esadecimale ASCII BidiControl controllo bidirezionalita` Dash trattino Deprecated deprecato Diacritic diacritico (accenti etc.) Extender estensore GraphemeLink collegamento tra grafemi HexDigit cifra esadecimale Hyphen trattino di sillabazione Ideographic ideografico IDSBinaryOperator operatore binario IDS IDSTrinaryOperator operatore ternario IDS JoinControl controllo di legatura LogicalOrderException eccezione di ordine logico NoncharacterCodePoint code point non carattere OtherAlphabetic altri alfabetici OtherDefaultIgnorableCodePoint altro code point normalmente ignorabile OtherGraphemeExtend altra estensione di grafema OtherLowercase altra minuscola OtherMath altro carattere matematico OtherUppercase altra maiuscola QuotationMark virgoletta Radical radicale SoftDotted con puntino eliminabile TerminalPunctuation punteggiatura terminale UnifiedIdeograph ideogramma unificato WhiteSpace spazio
e ci sono ancora proprietà derivate:
Alphabetic Lu + Ll + Lt + Lm + Lo + OtherAlphabetic Lowercase Ll + OtherLowercase Uppercase Lu + OtherUppercase Math Sm + OtherMath
ID_Start Lu + Ll + Lt + Lm + Lo + Nl ID_Continue ID_Start + Mn + Mc + Nd + Pc
Any Ogni carattere Assigned Ogni carattere non in Cn (sinonimo di \P{Cn}) Unassigned Sinonimo di \p{Cn} Common Ogni carattere (o code point non assegnato) non esplicitamente assegnato a uno script
Per compatibilità con Perl 5.6, tutte le proprietà
menzionate finora possono essere indicate anche preponendo Is
al
loro nome, per cui as esempio \P{IsLu}
è uguale a
\P{Lu}
.
Oltre agli script, Unicode definisce anche dei blocchi di
caratteri. La differenza tra script e blocchi è che il
concetto di script è più vicino ai linguaggi naturali,
mentre il concetto di blocco è più un raggruppamento
artificioso basato su gruppi di 256 caratteri. Ad esempio, lo script
Latin contiene lettere da svariati blocchi, ma non contiene ciascun
carattere da tutti quei blocchi. Ad esempio, non contiene le cifre,
essendo queste condivise tra molti script. Cifre e altri caratteri
condivisi, come ad esempio la punteggiatura, appartengono alla
categoria chiamata Common
.
Per maggiori informazioni sugli script, leggete UTR #24:
http://www.unicode.org/unicode/reports/tr24/
Per maggiori informazioni sui blocchi, leggete:
http://www.unicode.org/Public/UNIDATA/Blocks.txt
I nomi dei blocchi si indicano con il prefisso In
. Ad esempio, per
far match sui caratteri del blocco Katakana si usa
\p{InKatakana}
. Il prefisso In
può essere omesso se non
ci sono conflitti con il nome di uno script o di un'altra
proprietà, ma si raccomanda di usare sempre In
per indicare
i blocchi, per evitare confusione.
Sono supportati i seguenti nomi di blocco:
InAlphabeticPresentationForms InArabic InArabicPresentationFormsA InArabicPresentationFormsB InArmenian InArrows InBasicLatin InBengali InBlockElements InBopomofo InBopomofoExtended InBoxDrawing InBraillePatterns InBuhid InByzantineMusicalSymbols InCJKCompatibility InCJKCompatibilityForms InCJKCompatibilityIdeographs InCJKCompatibilityIdeographsSupplement InCJKRadicalsSupplement InCJKSymbolsAndPunctuation InCJKUnifiedIdeographs InCJKUnifiedIdeographsExtensionA InCJKUnifiedIdeographsExtensionB InCherokee InCombiningDiacriticalMarks InCombiningDiacriticalMarksforSymbols InCombiningHalfMarks InControlPictures InCurrencySymbols InCyrillic InCyrillicSupplementary InDeseret InDevanagari InDingbats InEnclosedAlphanumerics InEnclosedCJKLettersAndMonths InEthiopic InGeneralPunctuation InGeometricShapes InGeorgian InGothic InGreekExtended InGreekAndCoptic InGujarati InGurmukhi InHalfwidthAndFullwidthForms InHangulCompatibilityJamo InHangulJamo InHangulSyllables InHanunoo InHebrew InHighPrivateUseSurrogates InHighSurrogates InHiragana InIPAExtensions InIdeographicDescriptionCharacters InKanbun InKangxiRadicals InKannada InKatakana InKatakanaPhoneticExtensions InKhmer InLao InLatin1Supplement InLatinExtendedA InLatinExtendedAdditional InLatinExtendedB InLetterlikeSymbols InLowSurrogates InMalayalam InMathematicalAlphanumericSymbols InMathematicalOperators InMiscellaneousMathematicalSymbolsA InMiscellaneousMathematicalSymbolsB InMiscellaneousSymbols InMiscellaneousTechnical InMongolian InMusicalSymbols InMyanmar InNumberForms InOgham InOldItalic InOpticalCharacterRecognition InOriya InPrivateUseArea InRunic InSinhala InSmallFormVariants InSpacingModifierLetters InSpecials InSuperscriptsAndSubscripts InSupplementalArrowsA InSupplementalArrowsB InSupplementalMathematicalOperators InSupplementaryPrivateUseAreaA InSupplementaryPrivateUseAreaB InSyriac InTagalog InTagbanwa InTags InTamil InTelugu InThaana InThai InTibetan InUnifiedCanadianAboriginalSyllabics InVariationSelectors InYiRadicals InYiSyllables
\X
fa match su una qualsiasi sequenza estesa
Unicode -- una sequenza di caratteri combinati, ``combining character
sequence'' nello standard -- in cui il primo carattere è un
carattere base e i seguenti sono modificatori che si applicano al
primo. \X
equivale a (?:\PM\pM*)
.
L'operatore tr///
trasforma caratteri invece che byte. Notare che
la funzionalità di tr///CU
è stata rimossa. Per
fare qualcosa di simile usate pack('U0', ...)
e pack('C0', ...)
.
Gli operatori di cambio tra maiuscole e minuscole usano le tabelle di
trasformazione Unicode quando vengono applicati a caratteri. Notate
che uc()
, o \U
nelle stringhe interpolate, trasforma in
maiuscolo, mentre ucfirst()
, o \u
nelle stringhe interpolate,
trasforma in ``maiuscole da titolo'', nelle lingue che hanno questa
distinzione.
La maggior parte degli operatori che trattano posizioni o lunghezze su
stringhe passeranno automaticamente a usare posizioni di caratteri;
tali operatori includono chop()
, chomp
, substr()
, pos()
,
index()
, rindex()
, sprintf()
, write()
, e length()
. Tra
gli operatori che esplicitamente non cambiano ci sono vec()
,
pack()
, e unpack()
.
Tra gli operatori per cui non fa differenza ci sono gli opertatori che
trattano le stringhe come mucchi di bit come sort()
, e gli
operatori che gestiscono i nomi di file.
c
e C
di pack()
e unpack()
non
cambiano, poiché vengono spesso usate per formati orientati ai
byte. Pensate al char
del linguaggio C.
Il nuovo specificatore U
converte tra caratteri Unicode e code point.
chr()
e ord()
lavorano sui caratteri, in maniera
simile a pack("U")
e unpack("U")
, e non come pack("C")
e
unpack("C")
. pack("C")
e unpack("C")
sono metodi per emulare
le funzioni chr()
e ord()
orientate ai byte su stringhe Unicode.
Sebbene questi metodi mostrino la codifica interna delle stringhe
Unicode, non si tratta di una cosa di cui dovreste normalmente
preoccuparvi.
Gli operatori per stringhe di bit, & | ^ ~
, possono lavorare su
dati a carattere. Però, per compatibilità all'indietro
con i casi in cui si usano questi operatori su stringhe i cui
caratteri hanno tutti valore inferiore a 256, non dovreste usare ~
(il complemento a bit) quando i caratteri hanno valori sia sotto sia
sopra 256. Più importante, le leggi di De Morgan
(~($x|$y) eq ~$x&~$y
e ~($x&$y) eq ~$x|~$y
) non varranno. La
ragione per questo sgarro matematico è che il complemento
non può restituire sia il complemento a 8 bit (byte) che
il complemento a larghezza di carattere.
lc()
, uc()
, lcfirst()
, e ucfirst()
funzionano nei seguenti
casi:
Ogni cosa che ha a che fare coi locale (Lituano, Turco, Azeri) non funziona, poirché Perl non capisce il concetto dei locale Unicode.
Leggete il rapporto tecnico Unicode #21, ``Case Mappings'' (``Trasformazioni tra maiuscole e minuscole'', NdT), per ulteriori dettagli.
E, infine,scalar reverse()
rovescia per caratteri anziché
per byte.
Potete definire le vostre proprietà di carattere definendo
delle subroutine con nomi che cominciano con In
o Is
. Queste
subroutine possono essere definite in un qualsiasi package. Le
proprietà definite dall'utente possono essere usate nei
costrutti \p
e \P
nelle espressioni regolari; se usate una
proprietà definite dall'utente in un package diverso da quello
in cui è definita, dovete specificare quest'ultimo package
all'interno di \p
o \P
:
# la proprieta` IsStraniero e` definita in Lang:: package main; # altro package: serve il nome completo if ($txt =~ /\p{Lang::IsStraniero}+/) { ... }
package Lang; # stesso package: basta il nome corto if ($txt =~ /\p{IsStraniero}+/) { ... }
Notare che l'effetto è a tempo di compilazione, ed è immutabile una volta definito.
Le subroutine devono restituire una stringa in formato speciale, contenente una o più linee separate da a-capo. Ciascuna linea deve avere uno dei formati seguenti:
+
: una delle proprietà
predefinite (preceduta da utf8::
) o una proprietà definita
dall'utente, per indicare tutti i caratteri in quella
proprietà; due numeri esadecimali per un intervallo di code
point; o un singolo code point in esadecimale.
Qualcosa da escludere, preceduto da -
: una delle proprietà
predefinite (preceduta da utf8::
) o una proprietà definita
dall'utente, per indicare tutti i caratteri in quella
proprietà; due numeri esadecimali per un intervallo di code
point; o un singolo code point in esadecimale.
Qualcosa da negare, preceduto da !
: una delle proprietà
predefinite (preceduta da utf8::
) o una proprietà definita
dall'utente, per indicare tutti i caratteri tranne quelli in quella
proprietà; due numeri esadecimali per un intervallo di code
point; o un singolo code point in esadecimale.
Qualcosa con cui fare l'intersenzione, preceduto da &
: una delle
proprietà predefinite (preceduta da utf8::
) o una
proprietà definita dall'utente, per indicare tutti i caratteri
tranne quelli in quella proprietà; due numeri esadecimali per
un intervallo di code point; o un singolo code point in esadecimale.
Ad esempio, per definire una proprietà che copra entrambi i sistemi sillabici giapponesi (hiragana e katakana) potete definire
sub InKana { return <<END; 3040\t309F 30A0\t30FF END }
(immaginando che il terminatore del documento immediato sia all'inizio
della riga). Ora potete usare \p{InKana}
e \P{InKana}
.
Avremmo anche potuto usare i nomi di blocchi esistenti:
sub InKana { return <<'END'; +utf8::InHiragana +utf8::InKatakana END }
Supponiamo che vogliate indicare solo i caratteri allocati, e non i semplici intervalli dei blocchi: in altre parole, volete rimuovere i non-caratteri:
sub InKana { return <<'END'; +utf8::InHiragana +utf8::InKatakana -utf8::IsCn END }
La negazione è utile per definire (sorpresa!) negazioni di classi:
sub InNotKana { return <<'END'; !utf8::InHiragana -utf8::InKatakana +utf8::IsCn END }
L'intersezione è utile per indicare i caratteri presenti in due (o più) classi.
sub InFooAndBar { return <<'END'; +main::Foo &main::Bar END }
È importante ricordare di non usare &
per il primo insieme:
vorrebbe dire fare l'intersezione col niente, e otterreste un insieme
vuoto.
Potete anche definire le vostre mappature da far usare a lc()
,
lcfirst()
, uc()
e ucfirst()
(o i loro equivalenti per le
stringhe interpolate). Il principio è lo stesso: definite
delle subroutine nel package main
con nome ToLower
(per lc()
e lcfirst()
), ToTitle
(per il primo carattere in ucfirst
), e
ToUpper
(per uc()
, e i caratteri successivi in ucfirst()
)).
La stringa restituita dalla subroutine ora deve contenere, per ciascuna riga, tre numeri esadecimali separati da tabulazioni: inizio dell'intervallo di partenza, fine dell'intervallo di partenza, inizio dell'intervallo di arrivo. Per esempio:
sub ToUpper { return <<END; 0061\t0063\t0041 END }
definisce una mappatura per uc()
che trasforma i soli caratteri
"a"
, "b"
e "c"
in "A"
, "B"
e "C"
, lasciando
inalterati tutti gli altri caratteri.
Se non ha senso parlare di intervallo di partenza, ovvero, se la mappatura interessa un solo carattere, lasciate vuota la fine dell'intervallo di partenza, ma dovete lasciare le due tabulazioni. Per esempio:
sub ToLower { return <<END; 0041\t\t0061 END }
definisce una mappatura per lc()
che trasforma il solo carattere
"A"
in "a"
, lasciando inalterati tutti gli altri caratteri.
(Per hacker più che abili) Se volete esaminare le mappature di
default, potete trovarne le definizioni nella directory
$Config{privlib}
/unicore/To/. I dati delle mappature vengono
restituiti dal documento immediato, e i vari utf::ToSpecQualcosa
sono eccezioni speciali ricavate da
$Config{privlib}
/unicore/SpecialCasing.txt. Le mappature
Digit
e Fold
presenti nella directory non sono direttamente
accessibili dall'utente: potete usare il modulo Unicode::UCD
, o
fare i match senza distinguere maiuscole da minuscole (è in
questo caso che viene usata la mappatura Fold
).
Una nota finale sulle proprietà e mappature definite dall'utente: vengono usate soltanto se lo scalare su cui si opera è stato marcato come contente caratteri Unicode. Il funzionamento sulle stringhe di byte non viene modificato.
Leggete the Encode manpage.
La seguente lista descrive tutte le funzionalità Unicode per espressioni regolari supportate al momento. I riferimenti a ``Livello N'' e i numeri di sezione si riferiscono al rapporto tecnico Unicode #18, ``Linee guida per le espressioni regolari Unicode'' (``Unicode Regular Expression Guidelines''), versione 6 (Unicode 3.2.0, Perl 5.8.0).
2.1 Notazione esadecimale - fatto [1] Notazione per nome - fatto [2] 2.2 Categorie - fatto [3][4] 2.3 Sottrazione - MANCA [5][6] 2.4 Limiti semplice di parola - fatto [7] 2.5 Match laschi semplici - fatto [8] 2.6 Fine linea - MANCA [9][10]
[ 1] \x{...} [ 2] \N{...} [ 3] . \p{...} \P{...} [ 4] c'e` il supporto per gli script (cfr. UTR#24 "Script Names"), i blocchi, le proprieta` binarie, le proprieta` enumerate, le proprieta` numeriche (come elencate in UTR#18 "Other Properties") [ 5] c'e` la negazione [ 6] potete usare il look-ahead [a] o definire apposite proprieta` [b] per emulare la sottrazione [ 7] includiamo la categoria C<Letters> tra i caratteri di parola [ 8] notare che Perl esegue il "Full case-folding" per i match, non il "Simple": as esempio, U+1F88 e` equivalente a U+1F00 U+03B9, non a U+1F80. Questo fa differenza per alcune lettere greche con alcuni modificatori: il "Full case-folding" decompone il carattere, mentre il "Simple" lo mapperebbe su un carattere singolo. [ 9] cfr. UTR#13 "Linee guida Unicode per i terminatori di linea" ("Unicode Newline Guidelines") [10] ^ e $ dovrebbero fare match anche su \x{85}, \x{2028} e \x{2029} (dovrebbe influenzare anche <>, $., e i numeri di riga) (\s fa match su \x{85}, \x{2028} and \x{2029})
[a] Potete simulare la sottrazione tra classi usando il look-ahead. Ad esmepio, quello che secondo UTR #18 potrebbe essere scritto come
[{Greek}-[{UNASSIGNED}]]
in Perl può essere scritto come:
(?!\p{Unassigned})\p{InGreekAndCoptic} (?=\p{Assigned})\p{InGreekAndCoptic}
Ma in questo particolare caso, probabilmente quello che volete è
\p{GreekAndCoptic}
che farà match sui caratteri assegnati facenti parti dello script greco.
Guardate anche il modulo Unicode::Regex::Set
: implementa l'intera
sintassi di raggruppamento, intersezione, unione e sottrazione di UTR
#18.
[b] Cfr. Proprietà dei caratteri definite dall'utente
Livello 2 - Supporto Unicode esteso3.1 Surrogati - MANCA [11] 3.2 Equivalenti canonici - MANCA [12][13] 3.3 Grafemi indipendenti da locale - MANCA [14] 3.4 Parole indipendenti da locale - MANCA [15] 3.5 Match laschi indipendenti da locale - MANCA [16]
[11] i surrogati sono un concetto limitato a UTF-16, e la rappresentazione interna di Perl e` UTF-8. Il modulo Encode tratta anche UTF-16. [12] cfr. UTR#15 "Normalizzazione Unicode" ("Unicode Normalization") [13] c'e` Unicode::Normalize ma non e` integrato con le espressioni regolari [14] c'e` \X ma a questo livello . dovrebbe essere equivalente [15] servono tre classi, non solo \w e \W [16] cfr. UTR#21 "Trasformazioni tra maiuscole e minuscole" ("Case Mappings")Livello 3 - Supporto dipendente da locale
4.1 Categorie dipendenti da locale - MANCA 4.2 Grafemi dipendenti da locale - MANCA [16][17] 4.3 Parole dipendenti da locale - MANCA 4.4 Match laschi dipendenti da locale - MANCA 4.5 Intervalli dipendenti da locale - MANCA
[16] cfr. UTR#10 "Algoritmi di collazione Unicode" ("Unicode Collation Algorithms") [17] c'e` Unicode::Collate ma non e` integrato con le espressioni regolari
I caratteri Unicode sono associati a code point, che sono numeri astratti. Per usare questi numeri, sono necessarie varie codifiche.
UTF-8 è una codifica a lunghezza variabile (da 1 a 6 byte, per tutti i caratteri attualmente allocati ne sono sufficienti 4), indipendente dall'ordinamento dei byte. La codifica UTF-8 è trasparente se ci si limita ad ASCII (e qui si intende davvero ASCII, 7 bit, non una qualche altra codifica a 8 bit).
La tabella seguente è presa da Unicode 3.2:
Code Point 1o byte 2o byte 3o byte 4o byte
U+0000..U+007F 00..7F U+0080..U+07FF C2..DF 80..BF U+0800..U+0FFF E0 A0..BF 80..BF U+1000..U+CFFF E1..EC 80..BF 80..BF U+D000..U+D7FF ED 80..9F 80..BF U+D800..U+DFFF ******* mal formato ******* U+E000..U+FFFF EE..EF 80..BF 80..BF U+10000..U+3FFFF F0 90..BF 80..BF 80..BF U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF U+100000..U+10FFFF F4 80..8F 80..BF 80..BF
Notate il A0..BF
per U+0800..U+0FFF
, il 80..9F
per
U+D000...U+D7FF
, il 90..BF
per U+10000..U+3FFFF
, e il
80...8F
per U+100000..U+10FFFF
. Questi ``buchi'' sono causati dal
fatto che UTF-8 corretto evita le codifiche non minime: tecnicamente
è possibile codificare in UTF-8 un singolo code point in
più di un modo, ma ciò è espressamente
proibito, e bisogna sempre usare la codifica più breve
possibile. Per cui questo è quello che fa Perl.
Un altro modo di vedere la codifica è a livello di bit:
Code Point 1o byte 2o byte 3o byte 4o byte
0aaaaaaa 0aaaaaaa 00000bbbbbaaaaaa 110bbbbb 10aaaaaa ccccbbbbbbaaaaaa 1110cccc 10bbbbbb 10aaaaaa 00000dddccccccbbbbbbaaaaaa 11110ddd 10cccccc 10bbbbbb 10aaaaaa
Come potete vedere, i byte seguenti cominciano tutti con 10
, e i
bit iniziali del primo byte indicano quanti byte fanno parte della
codifica del carattere.
Come UTF-8 ma ``EBCDIC-safe'', allo stesso modo che UTF-8 è ASCII-safe.
UTF-16, UTF-16BE, UTF-16LE, surrogati, e i BOM (Byte Order Mark)Quello che segue è soprattutto per riferimento e conoscenza generale di Unicode; Perl non usa questi costrutti internamente.
UTF-16 è una codifica a 2 o 4 byte. I code point
U+0000..U+FFFF
sono codificati in una singola unità da 16
bit, e i code point U+10000..U+10FFFF
sono codificati in due
unità da 16 bit. Quest'ultimo caso usa i surrogati, con la
prima unità chiamata surrogato alto (``high surrogate'' NdT)
e la seconda chiamata surrogato basso (``low surrogate'' NdT).
I surrogati sono code point lasciati da parte per codificare
l'intervallo di code point U+10000..U+10FFFF
in coppie di
unità da 16 bit. I surrogati alti sono nell'intervallo
U+D800..U+DBFF
, e i surrogati bassi sono nell'intervallo
U+DC00..U+DFFF
. La codifica con i surrogati è
$alto = ($uni - 0x10000) / 0x400 + 0xD800; $basso = ($uni - 0x10000) % 0x400 + 0xDC00;
e la decodifica è
$uni = 0x10000 + ($alto - 0xD800) * 0x400 + ($basso - 0xDC00);
Se provate a generare surrogati (ad esempio usando chr()
),
otterrete un avvertimento se gli avvertimenti sono abilitati,
poiché tali code point non sono validi per caratteri Unicode.
Avendo unità lunghe 16 bit, UTF-16 dipende dall'ordinamento dei byte. UTF-16 di per sé può essere usato in memoria, ma se deve essere trasmesso o salvato su file bisogna scegliere tra UTF-16BE (big-endian) e UTF-16LE (little-endian).
Questo introduce un altro problema: cosa succede se sapete solo che i
dati sono in UTF-16, ma non sapete in che ordine? I Byte Order Mark, o
BOM, sono una soluzione. Un carattere speciale è stato scelto in
Unicode per essere usato come Byte Order Mark: il carattere con code
point U+FEFF
è il BOM.
Il trucco è che se leggete un BOM, saprete l'ordinamento dei
byte, visto che se è stato scritto su una piattaforma
big-endian, leggerete i due byte 0xFE 0xFF
, ma se è stato
scritto su una piattaforma little-endian leggerete i due byte 0xFF
0xFE
. (E se la piattaforma di partenza scriveva in UTF-8, leggerete i
tre byte 0xEF 0xBB 0xBF
).
Questo trucco funziona perché il code point U+FFFE
è garantito non essere un carattere valido, per cui la
sequenza di byte 0xFF 0xFE
è senza ambiguità ``BOM
rappresentato in forma little-endian'' e non può essere
``U+FFFE
rappresentato in forma big-endian''.
La famiglia UTF-32 è molto simile a quella UTF-16, tranne per
il fatto che le unità sono di 32 bit, e di conseguenza non
serve il metodo dei surrogati. Le segnature BOM saranno 0x00 0x00
0xFE 0xFF
per BE e 0xFF 0xFE 0x00 0x00
per LE.
Codifiche definite dallo standard ISO 10646. UCS-2 è una
codifica a 16 bit. A differenza di UTF-16, UCS-2 non può
essere esteso oltre U+FFFF
, poiché non usa i
surrogati. UCS-4 è una codifica a 32 bit, funzionalmente
identica a UTF-32.
Una codifica a 7 bit (l'ottavo bit è sempre a 0), utile quando il sistema di trasferimento o immagazzinamento non gestisce bene dati a 8 bit. È definito dalla RFC 2152.
Sfortunatamente, la specifica di UTF-8 lascia un po' di spazio all'interpretazione su quanti byte di output codificato si debbano generare per un dato carattere Unicode di input. Strettamente parlando, dovrebbe essere generata la sequenza più breve possibile, poiché altrimenti c'è la possibilità di overflow del buffer di input dal lato di lettura di una connessione UTF-8. Perl genera sempre la sequenza più breve, e con gli avvertimenti attivati Perl vi avvertirà nel caso di UTF-8 a lunghezza non minima assieme ad altre malformazioni, come l'uso di surrogati, che non sono davvero code point Unicode.
Le espressioni regolari si comportano in maniera leggermente differente se applicate a stringhe di byte o a stringhe di caratteri (Unicode). Ad esempio, la classe ``caratteri di parola''\w
funzionerà in modo diverso nei due casi.
Nel primo caso, l'insieme di caratteri di \w
è piuttosto
ristretto: l'insieme di default di caratteri alfabetici, cifre, e il
``_
'' -- oppure, se state usando un ``locale'' (cfr. the perllocale manpage),
\w
potrebbe contenere alcune altre lettere a seconda della vostra
lingua e nazione.
Nel secondo caso, l'insieme di caratteri di \w
è molto,
molto più esteso. La cosa più importante è
che, anche limitatamente ai primi 256 caratteri, probabilmente
includerà caratteri diversi: a differenza della maggior parte
dei ``locale'', che sono specifici di una lingua e una nazione, Unicode
classifica come \w
tutti i caratteri che sono lettere da qualche
parte. Ad esempio, il vostro ``locale'' potrebbe non pensare che LATIN
SMALL LETTER ETH sia una lettera (tranne nel caso in cui parliate
Islandese), ma Unicode la tratta come tale.
Come discusso altrove, Perl tiene un piede (due zoccoli?) in ciascuno
dei due mondi: il vecchio mondo dei byte, e il nuovo mondo dei
caratteri, convertendo i byte in caratteri quando necessario.
Se il vostro codice esistente non usa esplicitamente Unicode, non
dovrebbe avvenire alcuna conversione automatica a caratteri. I
caratteri non dovrebbero neppure venire riconvertiti in byte. È
comunque possibile mescolare byte e caratteri (cfr. the perluniintro manpage),
nel qual caso \w
nelle espressioni regolari potrebbe cominciare a
comportarsi differentemente. Controllate il vostro codice. Usate gli
avvertimenti (``warning'') e la direttiva strict
.
La gestione di Unicode su piattaforme EBCDIC è ancora
sperimentale. Su tali piattaforme, i rifermenti alla codifica UTF-8 in
questo e altri documenti dovrebbero essere intesi come a indicare
UTF-EBCDIC, specificato dal rapporto tecnico Unicode 16, tranne nel
caso in cui si stiano proprio discutendo le differenze tra ASCII e
EBCDIC. Non esiste né una direttiva utfebcdic
né
uno strato :utfebcdic
; al loro posto, utf8
e :utf8
vengono
usati per indicare la codifica a 8 bit ``nativa'' della piattaforma per
Unicode. Leggete the perlebcdic manpage per una discussione più
approfondita della questione.
Normalmente le impostazione di ``locale'' e Unicode non si influenzano a vicenda, ma ci sono un paio di eccezioni:
@ARGV
, e l'uso di UTF-8 come strato implicito nelle
open()
, fornendo il parametro a linea di comando -C
o la
variabile d'ambiente PERL_UNICODE
; leggete the perlrun manpage per la
documentazione del parametro -C
.
Perl cerca con tutte le sue forze di lavorare sia con Unicode sia col
vecchio mondo a byte. Molto spesso questo è comodo, ma certe volte
tenere così ``il piede in due staffe'' può causare problemi.
Sebbene Perl abbia molti modi per gestire l'input e l'output in
Unicode, e i vari altri ``punti di ingresso dati'' come @ARGV
che
possono essere interpretati come Unicode (UTF-8), restano comunque
molti casi in cui Unicode (in una qualche codifica) potrebbe essere
fornito come parametro o ricevuto come risultato, ma non viene usato.
L'elenco seguente contiene tali interfacce. Per ciascuna di esse Perl
al momento (versione 5.8.3) si limita ad assumere che sia i parametri
che i risultati siano stringhe di byte, o stringhe UTF-8 se è
stata usata la direttiva encoding
.
Una delle ragioni per cui Perl non tenta di risolvere il ruolo di
Unicode in questi casi è che le risposte dipendono fortemente
dal sistema operativo e dal file system. Ad esempio, il fatto che i
nomi di file possano essere Unicode, e in quale particolare codifica,
non è un concetto proprio portabile. Allo stesso modo per
qx
e system
: come viene gestito Unicode dall'``interfaccia a riga
di comando''? (e di quale interfaccia si tratta?).
chdir
, chmod
, chown
, chroot
, exec
, link
, lstat
,
mkdir
, rename
, rmdir
, stat
, symlink
, truncate
,
unlink
, utime
, -X
%ENV
glob
(ovvero <*>
)
open
, opendir
, sysopen
qx
(ovvero l'operatore ``
), system
readdir
, readlink
In alcuni casi (vedi Quando Unicode non viene usato) dovete
proprio convincere Perl che una stringa di byte è in UTF-8, o
viceversa. Le chiamate di basso livello utf8::upgrade($bytestring)
e utf8::downgrade($utf8string)
sono la risposta.
Non usatele senza pensarci, però: Perl può
confondersi, arabbiarsi o dare errori fatali se cambiate al volo la
``natura'' degli scalari a quel modo. Dovete stare particolarmente
attenti se usate utf8::upgrade()
: una stringa di byte a caso non
è, in generale, UTF-8 valido.
Se volete maneggiare dati Perl in Unicode nelle vostre estensioni XS, potreste trovare utili le seguenti funzioni della API C. Leggete Supporto Unicode in the perlguts manpage per una spiegazione di Unicode a livello XS, e the perlapi manpage per i dettagli della API.
DO_UTF8(sv)
restituisce true se il flag UTF8
è attivo e
la direttiva bytes
non è in uso. SvUTF8(sv)
restituisce
true se il flag UTF8
è attivo, senza tener conto della
direttiva bytes
. Il fatto che il flag UTF8
sia attivo non
indica che lo scalare contenga caratteri con code point maggiori di
255 (o 127), e neppure che ci siano prorio caratteri. Il significato
del flag UTF8
è che la sequenza di ottetti nella
rappresentazione dello scalare è la sequenza codificata in
UTF-8 dei code point dei caratteri di una stringa. Il fatto che il
flag UTF8
sia a zero significa che ciascun ottetto in questa
rappresentazione codifica un solo carattere con code point tra 0 e 255
nella stringa. In modello Unicode del Perl consiste nel non usare
UTF-8 finché non è assolutamente necessario.
uvuni_to_utf8(buf, chr)
scrive il code point di un carattere
Unicode in un buffer, codificandolo in UTF-8, e restituisce un
puntatore che punta dopo i byte UTF-8.
utf8_to_uvuni(buf, lenp)
legge dei byte codificati in UTF-8 da un
buffer e restituisce i code point dei caratteri Unicode e,
opzionalmente, la lunghezza della sequenza di byte UTF-8.
utf8_length(start, end)
restituisce la lunghezza del buffer in
numero di caratteri codificati in UTF-8. sv_len_utf8(sv)
restituisce la lunghezza di scalari codificati in UTF-8.
sv_utf8_upgrade(sv)
converte la stringa dello scalare nella sua
forma codificata in UTF-8. sv_utf8_downgrade(sv)
fa l'opposto, se
possibile. sv_utf8_encode(sv)
è simile a
sv_utf8_upgrade
tranne che non imposta il flag
UTF8
. sv_utf8_decode()
fa l'opposto di sv_utf8_encode()
.
Notate che nessuna di queste funzioni deve essere usata come
interfaccia generica di codifica/decodifica: usate Encode
in questi
casi. sv_utf8_upgrade()
è influenzata dalla direttiva
encoding
, ma sv_utf8_downgrade()
no (poiché la direttiva
encoding
è progettata per essere una strada a senso unico).
is_utf8_char(s)
restituisce true se il puntatore punta a una
codifica valida in UTF-8 di un carattere.
is_utf8_string(buf, len)
restituisce true se len
byte del buffer
sono UTF-8 valido.
UTF8SKIP(buf)
restituisce il numero di byte usati dal carattere
codificato nel buffer. UNISKIP(chr)
restituisce il numero di byte
necessari per codificare in UTF-8 il code point del carattere
Unicode. UTF8SKIP()
è utile ad esempio per iterare sui
caratteri di un buffer codificato in UTF-8; UNISKIP()
è
utile, ad esempio, per calcolare la dimensione necessaria per un
buffer codificato in UTF-8.
utf8_distance(a, b)
restituisce la distanza in caratteri tra i due
puntatori che puntano allo stesso buffer codificato in UTF-8.
utf8_hop(s, off)
restituisce un puntatore a un buffer UTF-8 che
dista off
(positivo o negativo) caratteri dal buffer UTF-8
s
. Attenzione a non sforare: utf8_hop()
uscirà
tranquillamente dall'inizio o dalla fine del buffer se gli viene
richiesto.
pv_uni_display(dsv, spv, len, pvlim, flags)
e
sv_uni_display(dsv, ssv, pvlim, flags)
sono utili per la
visualizzazione in fase di debugging di stringhe e scalari
Unicode. Normalmente sono utili sono in fase di debugging -- mostrano
tutti i caratteri come code point in esadecimale -- ma usando i
flag UNI_DISPLAY_ISPRINT
, UNI_DISPLAY_BACKSLASH
, e
UNI_DISPLAY_QQ
potete renderne l'output più leggibile.
ibcmp_utf8(s1, pe1, u1, l1, u1, s2, pe2, l2, u2)
può essere
usata per confrontare due stringhe Unicode considerando uguali
maiuscole e minuscole. Per i confronti esatti usate semplicemente
memEQ()
e memNE()
come al solito.
Per ulteriori informazioni, leggete the perlapi manpage, e utf8.c e utf8.h nella distribuzione del codice sorgente di Perl.
L'uso dei ``locale'' con dati Unicode può portare a strani risultati. Al momento, Perl cerca di associare le informazioni di ``locale'' a 8 bit ai caratteri tra 0 e 255, ma questa tecnica è dimostrabilmente sbagliata per i ``locale'' che usano caratteri fuori da quell'intervallo quando vengono mappati su Unicode. Inoltre, il supporto Unicode di Perl funzionerà un po' più lentamente. L'uso dei ``locale'' con Unicode è scoraggiato.
Quando Perl scambia dati con un estensione, l'estensione dovrebbe
essere in grado di capire il flag UTF8
e agire di conseguenza. Se
l'estensione non sa come usare il flag, è probabile che
restituisca dati con il flag impostato in maniera scorretta.
Perciò se state lavorando con dati Unicode, consultate la documentazione di ciascun modulo che state usando se ci sono problemi con lo scambio di dati Unicode. Se la documentazione non parla di Unicode, sospettate il peggio, e magari guardate il sorgente per capire come è implementato il modulo. I moduli scritti interamente in Perl non dovrebbero causare problemi. Moduli che accedono, direttamente o indirettamente, codice scritto in altri linguaggi, sono a rischio.
Per le funzioni affette, la strategia semplice per evitare corruzione dei dati consiste nel rendere sempre esplicita la codifica dei dati scambiati. Scegliete una codifica che sapete che l'estensione sa gestire. Convertite gli argomenti da passare all'estensione in quella codifica, e riconvertite alla rovescia i risultati. Scrivete funzioni di interfaccia che facciano le conversioni al posto vostro, così che possiate sostituirle quando l'estensione verrà aggiornata.
Per fare un esempio, diciamo che la funzione Foo::Bar::escape_html
non gestisce ancora dati Unicode. La funzione di interfaccia converte
gli argomenti in UTF-8 semplice e converte il risultato di nuovo nella
rappresentazione interna Perl:
sub mio_escape_html ($) { my($cosa) = shift; return unless defined $cosa; Encode::decode_utf8(Foo::Bar::escape_html(Encode::encode_utf8($cosa))); }
Certe volte, quando l'estensione non converte i dati ma si limita a
immagazzinarli e recuperarli, vi troverete nella posizione di usare
l'altrimenti pericolosa funzione Encode::_utf8_on()
. Diciamo che
la popolare estensione Foo::Bar
, scritta in C, fornisce un metodo
param
che permette di immagazzinare e recuperare dati secondo
queste segnature:
$self->param($name, $value); # salva uno scalare $value = $self->param($name); # recupera uno scalare
Se l'estensione non fornisce ancora supporto per alcuna codifica,
potreste scrivere una classe derivata con un metodo param
come
questo:
sub param { my($self,$nome,$valore) = @_; utf8::upgrade($nome); # ora e` sicuramente UTF-8 if (defined $valore) utf8::upgrade($valore); # ora e` sicuramente UTF-8 return $self->SUPER::param($nome,$valore); } else { my $ret = $self->SUPER::param($nome); Encode::_utf8_on($ret); # sappiamo che e` UTF-8 return $ret; } }
Alcune estensioni forniscono filtri per i casi di entrata/uscita dei
dati, come la famiglia di DB_File::filter_store_key
. Cercate filtri
del genere nella documentazione delle vostre estensioni, possono
rendere la transizione a Unicode molto più facile.
Alcune funzioni sono più lente quando lavorano su stringhe
codificate in UTF-8 piuttosto che su stringhe di byte. Tutte le
funzioni che devono saltare caratteri, come length()
, substr()
o
index()
, o le espressioni regolari, lavorano molto più
velocemente quando i dati sono byte.
In Perl 5.8.0 questa lentezza era spesso piuttosto spettacolare; in
Perl 5.8.1 è stato introdotto un sistema di cache che dovrebbe
ridurre il problema, almeno per alcune operazioni. In generale, le
operazioni con stringhe UTF-7 restano lente. Ad esempio, le
proprietà Unicode (classi di caratteri) come \p{Nd}
sono
parecchio più lente (5-20 volte) delle corrispondenti semplici
come \d
(d'altra parte, ci sono 268 caratteri corrispondenti a
Nd
, contro i soli 10 per d
).
Perl 5.8 ha un modello Unicode diverso da quello di 5.6. In 5.6 il
programmatore doveva usare la direttiva utf8
per indicare che in un
particolare scope si stavano trattando dati Unicode, e doveva
assicurarsi che ci entrassero solo dati Unicode. Se avete del codice
che funziona sollo 5.6, avrete bisogno di alcuni tra gli aggiustamenti
seguenti. Gli esempi sono scritti in modo da continuare a funzionare
sotto 5.6, per cui dovreste poterli provare senza rischi.
if ($] > 5.007) { binmode $fh, ":utf8"; }Uno scalare che deve essere passato a qualche estensione
Per Compress::Zlib
, Apache::Request
o ogni altra estensione che
non cita Unicode nella documentazione, dovete disattivare il flag
UTF8
. Notare che tra quando scriviamo questo testo (Ottobre 2002) e
quando lo leggete, lo stato dei moduli citati può essere
cambiato: leggetene la documentazione per essere sicuri.
if ($] > 5.007) { require Encode; $val = Encode::encode_utf8($val); # ottiene ottetti }Uno scalare proveniente da un'estensione
Se siete convinti che lo scalare contenga UTF-8, molto probabilmente
volete impostare il flag UTF8
:
if ($] > 5.007) { require Encode; $val = Encode::decode_utf8($val); }Stessa cosa, ma solo se siete davvero sicuri
if ($] > 5.007) { require Encode; Encode::_utf8_on($val); }Una funzione di aiuto per
fetchrow_array
e fetchrow_hashref
Quando il database contiene soltanto UTF-8, una funzione o un metodo
di aiuto permette di sostituire comodamente le chiamate a
fetchrow_array
e fetchrow_hashref
. Permetterà anche di
adattarsi più facilmente a future migliorie nel dirver del
vostro database. Notare che quando scriviamo questo (Ottobre 2002),
DBI non ha un modo standard per gestire i dati UTF-8. Controllate la
documentazione relativa per vedere se sia ancora così.
sub fetchrow { my($self, $sth, $cosa) = @_; # $cosa e` uno tra fetchrow_{array,hashref} if ($] < 5.007) { return $sth->$cosa; } else { require Encode; if (wantarray) { my @arr = $sth->$cosa; for (@arr) { defined && /[^\000-\177]/ && Encode::_utf8_on($_); } return @arr; } else { my $ret = $sth->$cosa; if (ref $ret) { for my $k (keys %$ret) { defined && /[^\000-\177]/ && Encode::_utf8_on($_) for $ret->{$k}; } return $ret; } else { defined && /[^\000-\177]/ && Encode::_utf8_on($_) for $ret; return $ret; } } } }Un grande scalare che sapete contiene soltanto ASCII
Gli scalari che contengono soltanto ASCII ma sono marcati come UTF-8
impongono a volte dei rallentamenti ai vostri programmi. Se vi trovate
in una situazione del genere, basta che togliate il flag UTF8
:
utf8::downgrade($val) if $] > 5.007;
the perluniintro manpage, the encoding manpage, the Encode manpage, the open manpage, the utf8 manpage, the bytes manpage, the perlretut manpage, ${^UNICODE} in the perlvar manpage
La versione su cui si basa questa traduzione è ottenibile con:
perl -MPOD2::IT -e print_pod perlunicode
Per maggiori informazioni sul progetto di traduzione in italiano si veda http://pod2it.sourceforge.net/ .
Traduzione a cura di Gianni Ceccarelli.
NOME |