首页 > 解决方案 > 从变量中包含的代码和文件中打印 unicode 字符

问题描述

这里有一些代码没有做我希望它做的事情:

#!/usr/bin/perl -w 
use utf8;

binmode STDOUT, ":utf8";

# open a filehandle to a file that contains a single line of text: Hello \x{2744}!
open (H, "<:encoding(UTF-8)", "test.txt") || die $!;
while(<H>) {
    $line = $_;
    chomp($line);
    $var = "Hello \x{2744}!";
    $line = $line . " $var\n";

    print STDOUT "$line";
}

输出如下:

Hello \x{2744}! Hello ❄!

为什么它将我在脚本中分配的变量的内容打印为 unicode 字符,但对文件中包含的文本却不这样做?

我想我错过了一些明显的东西 - 欢迎任何指针!

标签: perlutf-8

解决方案


从文件中读取的行具有 Unicode 字符十六进制表示,但不是字符本身(表示字符的字节序列)。

该行需要用字符本身替换 Unicode 字符十六进制表示。

以下代码片段演示了实现所需输出的两种方法。

#!/usr/bin/perl
#
# vim: ai:ts=4:sw=4
#

use strict;
use warnings;
use feature 'say';

use Encode;
use utf8;

binmode STDOUT, ":utf8";

my @lines = (
    "Hello \x{2744}!",
    "Hello ❄!"
    );

while(my $line0=<DATA>) {
    chomp $line0;
    my $line1 = $line0;
    $line0 =~ s/\\x\{([\da-z]+)\}/decode('UTF-16',pack('H4',$1))/ieg;
    $line1 =~ s/\\x\{([\da-z]+)\}/chr(hex($1))/ieg;
    push @lines, $line0;
    push @lines, $line1;
}

say for @lines;

__DATA__
Hello \x{2744} you need \x{2602} to go under \x{2600}
Danger \x{2622} doctor Robinson, danger \x{2622}

输出

Hello ❄!
Hello ❄!
Hello ❄ you need ☂ to go under ☀
Hello ❄ you need ☂ to go under ☀
Danger ☢ doctor Robintson, danger ☢
Danger ☢ doctor Robintson, danger ☢

推荐阅读