How can I guess the encoding of a string in Perl?

前端 未结 3 1156
天命终不由人
天命终不由人 2020-11-30 03:46

I have a Unicode string and don\'t know what its encoding is. When this string is read by a Perl program, is there a default encoding that Perl will use? If so, how can I fi

3条回答
  •  情话喂你
    2020-11-30 04:30

    To find out in which encoding something unknown uses, you just have to try and look. The modules Encode::Detect and Encode::Guess automate that. (If you have trouble compiling Encode::Detect, try its fork Encode::Detective instead.)

    use Encode::Detect::Detector;
    my $unknown = "\x{54}\x{68}\x{69}\x{73}\x{20}\x{79}\x{65}\x{61}\x{72}\x{20}".
                  "\x{49}\x{20}\x{77}\x{65}\x{6e}\x{74}\x{20}\x{74}\x{6f}\x{20}".
                  "\x{b1}\x{b1}\x{be}\x{a9}\x{20}\x{50}\x{65}\x{72}\x{6c}\x{20}".
                  "\x{77}\x{6f}\x{72}\x{6b}\x{73}\x{68}\x{6f}\x{70}\x{2e}";
    my $encoding_name = Encode::Detect::Detector::detect($unknown);
    print $encoding_name; # gb18030
    
    use Encode;
    my $string = decode($encoding_name, $unknown);
    

    I find encode 'ascii' is a lame solution for getting rid of non-ASCII characters. Everything will be substituted with questions marks; this is too lossy to be useful.

    # Bad example; don't do this.
    use utf8;
    use Encode;
    my $string = 'This year I went to 北京 Perl workshop.';
    print encode('ascii', $string); # This year I went to ?? Perl workshop.
    

    If you want readable ASCII text, I recommend Text::Unidecode instead. This, too, is a lossy encoding, but not as terrible as plain encode above.

    use utf8;
    use Text::Unidecode;
    my $string = 'This year I went to 北京 Perl workshop.';
    print unidecode($string); # This year I went to Bei Jing  Perl workshop.
    

    However, avoid those lossy encodings if you can help it. In case you want to reverse the operation later, pick either one of PERLQQ or XMLCREF.

    use utf8;
    use Encode qw(encode PERLQQ XMLCREF);
    my $string = 'This year I went to 北京 Perl workshop.';
    print encode('ascii', $string, PERLQQ);  # This year I went to \x{5317}\x{4eac} Perl workshop.
    print encode('ascii', $string, XMLCREF); # This year I went to 北京 Perl workshop.
    

提交回复
热议问题