首页 > 解决方案 > 根据 ASCII 值拆分字符串

问题描述

我需要解析一个分隔文件。(由大型机作业生成并通过 ftp 传输到 Windows)。但是在使用分隔符上的拆分时得到的Q ueries 很少。

根据文档,文件由'1D'分隔。但是当我在记事本++中打开文件时(当我检查编码选项卡时,它被设置为'Encode in ANSI'),在我看来就像一个'垂直断线'。。不知道什么是“一维”?

在此处输入图像描述

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];

从 dumper 输出中,我们看到 perl 认为垂直折线的 ASCII 为 166。

根据link1, 166 确实是垂直虚线,而根据link2, 166 是女性序数指示符。Q.有什么关于为什么会有差异的建议吗?

my $str = $lines[0];
print Dumper $str;
# $VAR1 = 'AªBªCª';

我们可以看到输出包含“女性序数指标”而不是“垂直折线”。:不知道为什么 perl 会读取一个“bar”,然后开始将其视为其他东西。

# 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 作为参数。。将 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];

标签: perlascii

解决方案


当您收到来自未知来源的输入文件时,需要了解的最重要的事情是“它使用什么字符编码?” 如果没有这些信息,您对文件所做的任何处理都是基于猜测。

那些谈论“扩展ASCII”的人并没有解决这个问题,就好像它是一个有意义的术语一样。ASCII 仅包含 128 个字符。接下来的 128 个字符代码所代表的含义有很多定义,其中很多是相互矛盾的。

看来您有解决问题的方法。在 '¦' 上拆分(从 Notepad++ 复制)可以满足您的需求。所以我建议你这样做。如果要使用实际的字符代码,则可以将 116 转换为十六进制 (0xA6) 并使用:

split /\xA6/, ... ;

推荐阅读