gpt4 book ai didi

json - 使用 perl 对存储在 JSON 中的 utf8 文件名进行规范化

转载 作者:行者123 更新时间:2023-12-04 08:49:15 26 4
gpt4 key购买 nike

我有两个来自不同操作系统的 Json 文件。

两个文件都编码为 UTF-8并包含 UTF-8编码 filenames .

一个文件来自 OS X,文件名采用 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

第二个包含相同的文件名,但采用 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

据我所知,这被称为“不同规范化”,并且有一个 CPAN 模块 Unicode::Normalize处理它。

我正在阅读以下两个文件:
my $json1 = decode_json read_file($file1, {binmode => ':raw'}) or die "..." ;
my $json2 = decode_json read_file($file2, {binmode => ':raw'}) or die "..." ;

read_file 来自 File::Slurp和来自 JSON::XS 的 decode_json .

将 JSON 读入 perl 结构,从一个 json 文件中文件名进入 key位置并从第二个文件进入 values .我需要搜索哈希时 key从第一个哈希开始是 等效 value从第二个哈希,所以需要确保它们是“二进制”相同的。

尝试了下一个:
 grep 'House' file1.json | perl -CSAD -MUnicode::Normalize -nlE 'print NFD($_)' | od -bc


 grep 'House' file2.json | perl -CSAD -MUnicode::Normalize -nlE 'print NFD($_)' | od -bc

为我产生相同的输出。

现在的问题:
  • 如何简单读取两个 json 文件以获得相同的规范化到两个 $hashrefs ?

  • 或者需要 decode_json之后在两个哈希上运行类似的东西?
    while(my($k,$v) = each(%$json1)) {
    $copy->{ NFD($k) } = NFD($v);
    }

    简而言之:
  • 如何在 perl $href 中读取不同的 JSON 文件以获得相同的规范化?显式执行 NFD 可能会更好一些。在每个 key value并创建另一个 NFD 标准化(大)哈希副本?

  • 一些提示,建议 - 请...

    因为我的英文很差,这里是 模拟问题的
    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

    最佳答案

    在为您的问题寻找正确的解决方案时,我发现:该软件是 c*rp :) 请参阅:https://stackoverflow.com/a/17448888/632407 .

    无论如何,为您的特定问题找到了解决方案 - 如何使用文件名读取 json 而不管规范化:

    而不是你的:

    #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" ;

    使用下一个:
    #now read them
    my $jc = get_json_from_utf8_file('nfc.json') ;
    my $jd = get_json_from_utf8_file('nfd.json') ;
    ...

    sub get_json_from_utf8_file {
    my $file = shift;
    return
    decode_json #let parse the json to perl
    encode 'utf8', #the decode_json want utf8 encoded binary string, encode it
    NFC #conv. to precomposed normalization - regardless of the source
    read_file #your file contains utf8 encoded text, so read it correctly
    $file, { binmode => ':utf8' } ;
    }

    这应该(至少我希望)确保而不考虑什么分解使用 JSON 内容, NFC会将其转换为预先组合的版本,并且 JSON:XS 将正确读取并将其解析为相同的内部 perl 结构。

    所以你的例子打印:
    something

    无需遍历 $json
    这个想法来自约瑟夫迈尔斯和尼莫;)

    也许一些更熟练的程序员会给出更多的提示。

    关于json - 使用 perl 对存储在 JSON 中的 utf8 文件名进行规范化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17434027/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com