我需要解析一个定界文件(由大型机作业生成并通过ftp传输到Windows)。但是在定界符上进行分割时, Q 项很少。
根据文档,文件由'1D'分隔。但是,当我在记事本++中打开文件时(当我检查编码选项卡时,将其设置为“在ANSI中编码” ),在我看来,这就像是一个“垂直折线”。 Q 。不确定什么是“一维”?
open my $handle, '<', 'sample.txt';
chomp(my @lines = <$handle>);
close $handle;
my @a = unpack("C*", $lines[0]);
print Dumper \@a;
# $VAR1 = [65,166,66,166,67,166];
从转储器的输出中,我们看到perl认为垂直折线的ASCII为166。
根据link1,确实是166个垂直虚线,而根据link2,则是166个女性的序号指示符。问。关于为什么存在差异的任何建议? / p>
my $str = $lines[0];
print Dumper $str;
# $VAR1 = 'AªBªCª';
我们可以看到输出包含“女性顺序指示符”而不是“垂直折线”。问。不确定为什么perl会读取“ bar”,然后开始将其视为其他内容。< / p>
# I copied the vertical broken bar from notepad++ for use below
my @b = split(/¦/, $lines[0]);
print Dumper \@b;
# $VAR1 = [ 'AªBªCª' ];
由于perl开始像预期的那样将bar视为其他东西,因此这里没有拆分。我想通过直接给出166的ascii代码来拆分。似乎split()不支持ASCII作为参数。 Q 。将ASCII代码传递给split()的任何解决方法?
# I copied the vertical broken bar from notepad++ and created A¦B¦C
my @c = split(/¦/, 'A¦B¦C');
print Dumper \@c;
#$VAR1 = [ 'A','B','C']; # works as expected, added here just for completion
任何指针都会有很大帮助!
Update:
my @a = map {ord $_} split //, $lines[0]; print Dumper \@a;
# $VAR1 = [ 65,166,66,166,67,166];
答案 0 :(得分:2)
当您从未知来源收到输入文件时,最需要了解的是“它使用什么字符编码?”。没有这些信息,您对文件所做的任何处理都是基于猜测。
谈论“扩展的ASCII”的人并没有解决该问题,尽管这是一个有意义的术语。 ASCII仅包含128个字符。接下来的128个字符代码代表什么定义,其中很多是矛盾的。
看来您有解决问题的办法。在“ ¦”(从Notepad ++复制)上拆分即可满足您的需求。所以我建议你这样做。如果要使用实际的字符代码,则可以将116转换为十六进制(0xA6)并使用:
split /\xA6/, ... ;
答案 1 :(得分:2)
您应该始终解码输入并编码输出。
my $acp;
BEGIN {
require Win32;
$acp = "cp".Win32::GetACP();
}
use open ':std', ":encoding($acp)";
现在,@lines
将包含Unicode代码点的字符串。这样,您现在可以使用以下内容:
use utf8; # Source code is encoded using UTF-8.
my @b = split(/¦/, $lines[0]);
或者,以下每个选项现在也都可以使用:
my @b = split(/\N{BROKEN BAR}/, $lines[0]);
my @b = split(/\N{U+00A6}/, $lines[0]);
my @b = split(/\x{A6}/, $lines[0]);
my @b = split(/\xA6/, $lines[0]);