Vol*_*Kem 3 perl encoding utf-8 cp1251
我尝试将字符串转换为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";
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我得到了我需要的东西:
# ./convert.pl
converted:
?????? ?????
Run Code Online (Sandbox Code Playgroud)
但是如果我使用外部变量:
#!/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";
Run Code Online (Sandbox Code Playgroud)
什么都没发生.
# ./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
Run Code Online (Sandbox Code Playgroud)
这是第一个例子的转储:
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
Run Code Online (Sandbox Code Playgroud)
第二个:
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
Run Code Online (Sandbox Code Playgroud)
我试过这个方法:
#!/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
Run Code Online (Sandbox Code Playgroud)
但同样,这不是我需要的.你能帮助我在第一个脚本中得到结果吗?
使用完之后
($str = shift) =~ s/\\([0-7]+)/chr oct $1/eg
Run Code Online (Sandbox Code Playgroud)
正如鲍罗丁所说,我明白这一点
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
Run Code Online (Sandbox Code Playgroud)
目前尚不清楚你正在获得什么输入,输入的位置,输出是什么,但你不应该将数据编码为UTF-8以便在程序中使用,因为你想要处理字符而不是编码字节.您应该从正在发送到程序的任何外部编码中解码它并像这样使用它
听起来输入是Windows-1251,输出是UTF-8(?),我认为反斜杠是一种分心.文件中没有反斜杠或键盘上键入了吗?因此,为了清晰起见,将基数更改为十六进制,输入字符串就是这样
"\xD0\xC0\xC4\xC8\xD3\xD1\x20\xCE\xD0\xC0\xCA\xCB"
Run Code Online (Sandbox Code Playgroud)
并且你想将它转换为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;
Run Code Online (Sandbox Code Playgroud)
?????? ?????
Run Code Online (Sandbox Code Playgroud)
但这是一种人为的情况.该字符串实际上来自输入流,因此最好设置流的编码并忘记手动解码.binmode如果您正在阅读STDIN,可以使用,就像这样
binmode STDIN, 'encoding(Windows-1251)';
Run Code Online (Sandbox Code Playgroud)
然后从STDIN输入的文本将从Windows-1251编码的字节隐式转换为字符串.或者,如果您在自己的句柄上打开文件,则可以将编码放入open调用中
open my $fh, '<:encoding(Windows-1251)', $file or die $!;
Run Code Online (Sandbox Code Playgroud)
然后你不需要添加binmode任何一个
正如我所说,我假设您的输出是UTF-8,并且在线上方的程序中
use open qw/ :std OUT :encoding(UTF-8) /;
Run Code Online (Sandbox Code Playgroud)
将所有输出文件句柄设置为默认的UTF-8编码.它:std还将内置句柄STDOUT和STDERR设置为UTF-8.如果这不是你想要的,你无法弄清楚如何根据需要设置它,那么请问