Ho due file Json che provengono da diversi SO.Normalizzazione sui nomi file utf8 memorizzati in JSON con perl
Entrambi i file sono codificati in UTF-8
e contengono filenames
codificato .
Un file proviene da OS X e il nome del file è in forma NFD: (od -bc
)
0000160 166 145 164 154 141 314 201 057 110 157 165 163 145 040 155 145
v e t l a ́ ** / H o u s e m e
il secondo contiene lo stesso nome file ma in forma NFC:
000760 166 145 164 154 303 241 057 110 157 165 163 145 040 155 145 163
v e t l á ** / H o u s e m e s
come ho imparato , questo si chiama 'normalizzazione diversa', e c'è un modulo CPAN Unicode::Normalize
per gestirlo.
Sto leggendo entrambi i file con il prossimo:
my $json1 = decode_json read_file($file1, {binmode => ':raw'}) or die "..." ;
my $json2 = decode_json read_file($file2, {binmode => ':raw'}) or die "..." ;
Il read_file è da File::Slurp
e decode_json dal JSON::XS
.
Lettura del JSON in struttura perl, da un file json il nome del file viene immesso nella posizione key
e dal secondo file entra nello values
. Devo cercare quando l'hash key
dal primo hash è equivoco a un value
dal secondo hash, quindi è necessario assicurarsi che siano "binari" identici.
provato il prossimo:
grep 'House' file1.json | perl -CSAD -MUnicode::Normalize -nlE 'print NFD($_)' | od -bc
e
grep 'House' file2.json | perl -CSAD -MUnicode::Normalize -nlE 'print NFD($_)' | od -bc
produce per me la stessa uscita.
Ora le domande:
- Come semplicemente leggere entrambi i file JSON per ottenere lo stesso normalizzazione in entrambi
$hashrefs
?
o è necessario dopo il decode_json
eseguire qualcosa come su entrambi gli hash?
while(my($k,$v) = each(%$json1)) {
$copy->{ NFD($k) } = NFD($v);
}
In breve:
- Come leggere diversi file JSON per ottenere la stessa normalizzazione 'dentro' il perl
$href
? È possibile ottenere un po 'più bello come fare esplicitamenteNFD
su ognikey
value
e creare un'altra copia NFD normalizzata (grande) degli hash?
Alcuni suggerimenti, suggerimenti - pleae ...
perché il mio inglese è molto cattivo, ecco una simulazione del problema
use 5.014;
use warnings;
use utf8;
use feature qw(unicode_strings);
use charnames qw(:full);
use open qw(:std :utf8);
use Encode qw(encode decode);
use Unicode::Normalize qw(NFD NFC);
use File::Slurp;
use Data::Dumper;
use JSON::XS;
#Creating two files what contains different "normalizations"
my($nfc, $nfd);;
$nfc->{ NFC('key') } = NFC('vál');
$nfd->{ NFD('vál') } = 'something';
#save as NFC - this comes from "FreeBSD"
my $jnfc = JSON::XS->new->encode($nfc);
open my $fd, ">:utf8", "nfc.json" or die("nfc");
print $fd $jnfc;
close $fd;
#save as NFD - this comes from "OS X"
my $jnfd = JSON::XS->new->encode($nfd);
open $fd, ">:utf8", "nfd.json" or die("nfd");
print $fd $jnfd;
close $fd;
#now read them
my $jc = decode_json read_file("nfc.json", { binmode => ':raw' }) or die "No file" ;
my $jd = decode_json read_file("nfd.json", { binmode => ':raw' }) or die "No file" ;
say $jd->{ $jc->{key} } // "NO FOUND"; #wanted to print "something"
my $jc2;
#is here a better way to DO THIS?
while(my($k,$v) = each(%$jc)) {
$jc2->{ NFD($k) } = NFD($v);
}
say $jd->{ $jc2->{key} } // "NO FOUND"; #OK
nel frattempo mi trovi esattamente questa soluzione. Grazie. – kobame