In che modo le stringhe perl sono rappresentate internamente? Quale codifica viene utilizzata? Come gestisco correttamente le diverse codifiche?Interni di stringhe Perl
Utilizzo perl da molto tempo, ma non includeva molta gestione delle stringhe in codifiche diverse e quando ho riscontrato un problema minore che aveva a che fare con le codifiche, di solito ricorrevo ad alcune azioni sciamaniche.
Fino a questo momento ho pensato a stringhe perl come sequenze di byte, che si adattavano bene ai miei compiti. Ora ho bisogno di fare un po 'di elaborazione del file con codifica UTF-8 e qui iniziano i problemi.
In primo luogo, ho letto file in stringa come questa:
open(my $in, '<', $ARGV[0]) or die "cannot open file $ARGV[0] for reading";
binmode($in, ':utf8');
my $contents;
{
local $/;
$contents = <$in>;
}
close($in);
poi semplicemente stamparlo:
print $contents;
e ottengo due cose: un avvertimento Wide character in print at <scriptname> line <n>
e un bidone della spazzatura in consolle. Quindi posso concludere che le stringhe di perl hanno un concetto di "carattere" che può essere "ampio" o no, ma quando vengono stampati questi caratteri "larghi" sono rappresentati in console come byte multipli, non come singoli "caratteri". (Mi chiedo ora perché tutta la mia precedente esperienza con i file binari ha funzionato abbastanza come mi aspettavo che funzionasse senza problemi di "carattere").
Perché poi vedo la spazzatura in console? Se perl memorizza stringhe come carattere in alcune codifiche conosciute, non penso che ci sia un grosso problema a scoprire la codifica della console e stampare correttamente il testo. (Io uso Windows, BTW).
Se perl memorizza stringhe come sequenze di caratteri a larghezza variabile (ad esempio utilizzando la stessa codifica UTF-8), perché viene eseguita in questo modo? Dalla mia esperienza di gestione delle stringhe C è il dolore.
Aggiornamento.
Io uso due computer per il test, uno esegue Windows 7 x64 con il language pack inglese installato, ma con le impostazioni regionali russe (quindi ho cp866 come codepage OEM e cp1251 come ANSI) con ActivePerl 5.10.1 x64; un altro esegue localizzazione russa a 32 bit di Windows XP con Cygwin Perl 5.10.0.
Grazie ai collegamenti, ora ho una comprensione molto più solida su cosa sta succedendo e su come le cose dovrebbero essere fatte.
Per stringhe multi-byte intendevo la codifica a larghezza variabile. – n0rd
Ad ogni modo non capisco perché devo fare una conversione esplicita: ho specificato la codifica dei dati di input perché devo fare qualche passo in più? – n0rd
Hai specificato la codifica di input. Fai le tue cose. Quindi si specifica la codifica di output. Gli articoli cui ho fatto riferimento spiegano meglio, dovrei pensare. – dylan