gpt4 book ai didi

Perl:从 cp1251 转换为 utf8

转载 作者:行者123 更新时间:2023-12-01 10:37:14 24 4
gpt4 key购买 nike

我尝试将字符串转换为 utf8。

#!/usr/bin/perl -w
use Encode qw(encode decode is_utf8);
$str = "\320\300\304\310\323\321 \316\320\300\312\313";
Encode::from_to($str, 'windows-1251', 'utf-8');
print "converted:\n$str\n";

在这种情况下,我得到了我需要的:

# ./convert.pl
converted:
РАДИУС ОРАКЛ

但是如果我使用外部变量:

#!/usr/bin/perl -w
use Encode qw(encode decode is_utf8);
$str = $ARGV[0];
Encode::from_to($str, 'windows-1251', 'utf-8');
print "converted:\n$str\n";

没有任何反应。

# ./convert.pl "\320\300\304\310\323\321 \316\320\300\312\313"
converted:
\320\300\304\310\323\321 \316\320\300\312\313

这是第一个例子的转储:

SV = PV(0x1dceb78) at 0x1ded120
REFCNT = 1
FLAGS = (POK,pPOK)
PV = 0x1de7970 "\320\300\304\310\323\321 \316\320\300\312\313"\0
CUR = 12
LEN = 16

第二个:

SV = PV(0x1c1db78) at 0x1c3c110
REFCNT = 1
FLAGS = (POK,pPOK)
PV = 0x1c5e7e0 "\\320\\300\\304\\310\\323\\321 \\316\\320\\300\\312\\313"\0
CUR = 45
LEN = 48

我试过这个方法:

#!/usr/bin/perl -w
use Devel::Peek;
$str = pack 'C*', map oct, $ARGV[0] =~ /\\(\d{3})/g;
print Dump ($str);

# ./convert.pl "\320\300\304\310\323\321 \316\320\300\312\313"

SV = PV(0x1c1db78) at 0x1c3c110
REFCNT = 1
FLAGS = (POK,pPOK)
PV = 0x1c5e7e0 "\320\300\304\310\323\321\316\320\300\312\313"\0
CUR = 11
LEN = 48

但这又不是我所需要的。你能帮我得到第一个脚本中的结果吗?


使用后

($str = shift) =~ s/\\([0-7]+)/chr oct $1/eg

按照 Borodin 的建议,我明白了

SV = PVMG(0x13fa7f0) at 0x134d0f0
REFCNT =
FLAGS = (SMG,POK,pPOK)
IV = 0
NV = 0
PV = 0x1347970 "\320\300\304\310\323\321 \316\320\300\312\313"\0
CUR = 12
LEN = 16
MAGIC = 0x1358290
MG_VIRTUAL = &PL_vtbl_mglob
MG_TYPE = PERL_MAGIC_regex_global(g)
MG_LEN = -1

最佳答案

不清楚你从哪里得到什么输入,或者你想要输出什么,但是你不应该将你的数据编码成 UTF-8 以便在程序中使用,因为你想处理字符 而不是编码字节。您应该只从发送给程序的任何外部编码解码它,然后像那样使用它

听起来输入是 Windows-1251,输出是 UTF-8 (?),我认为反斜杠会分散注意力。文件中没有反斜杠或在键盘上输入了吗?因此,为了清楚起见,将基数更改为十六进制,您的输入字符串是这样的

"\xD0\xC0\xC4\xC8\xD3\xD1\x20\xCE\xD0\xC0\xCA\xCB"

并且您想将它转换为 Perl 字符串,用它做一些事情,然后将它打印到输出中。如果你在 Linux 机器上并且你想从原始输入字节显式解码它,那么你需要写这样的东西

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

use open qw/ :std OUT :encoding(UTF-8) /;
use Encode qw/ decode /;

my $str = "\xD0\xC0\xC4\xC8\xD3\xD1\x20\xCE\xD0\xC0\xCA\xCB";

$str = decode('Windows-1251', $str);

say $str;

输出

РАДИУС ОРАКЛ

但这是人为的情况。该字符串实际上来自输入流,因此最好设置流的编码并忘记手动解码。如果您从 STDIN 读取数据,您可以使用 binmode,就像这样

binmode STDIN, 'encoding(Windows-1251)';

然后来自 STDIN 的文本输入将从 Windows-1251 编码的字节隐式转换为字符串。或者,如果您在自己的句柄上打开文件,则可以将编码放入 open 调用

open my $fh, '<:encoding(Windows-1251)', $file or die $!;

然后你也不需要添加binmode

正如我所说,我假设您的输出是 UTF-8,并且在该行上方的程序中

use open qw/ :std OUT :encoding(UTF-8) /;

将所有输出 文件句柄设置为默认的UTF-8 编码。 :std 还将内置句柄 STDOUT 和 STDERR 设置为 UTF-8。如果这不是您想要的,并且您不知道如何根据需要进行设置,那么请务必询问

关于Perl:从 cp1251 转换为 utf8,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33116228/

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