我需要读取包含任意MBCS编码字符串的文本文件。文件格式(简化)如下:
CODEPAGE "STRING"
CODEPAGE STRING
...其中CODEPAGE可以是任何MBCS代码页: UTF-8、cp1251 (西里尔文)、cp932 (日文)等。
我不能在一次对MultiByteToWideChar的调用中解码整个文件。我需要提取引号之间的字符串,或者直到空格或回车符,并对提取的字符串调用MultiByteToWideChar。
但是在MBCS (多字节编码方案)中,一个字符可以用多于一个字节来表示。如果我想在多字节编码文件中找到拉丁语'A‘,我不能只搜索代码65,因为在某些编码序列中,65可能是尾随字节。
我浏览了几个代码页(例如中文的936代码页:https://ssl.icu-project.org/icu-bin/convexp?conv=windows-936-2000&s=ALL),就我所看到的所有尾随字节都是从0x40开始的,所以可以安全地扫描文件中的标点符号字符。但是对于任何代码页,这是有保证的吗?
发布于 2019-07-31 16:30:47
分析编码的二进制八位数序列中可能出现的二进制八位数,丢弃开头的那个。结果为0x40..0x7E,0x80..0xFE。
#!/usr/bin/env perl
use Encode qw(encode);
my @encodings = qw(
cp1006 cp1026 cp1047 cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256
cp1257 cp1258 cp37 cp424 cp437 cp500 cp737 cp775 cp850 cp852 cp855 cp856
cp857 cp858 cp860 cp861 cp862 cp863 cp864 cp865 cp866 cp869 cp874 cp875
cp932 cp936 cp949 cp950
);
my %continuation_octets;
for my $e (@encodings) {
for my $c (0..0x10_ffff) {
my $encoded = encode $e, chr($c), sub { -1 };
if ($encoded ne -1 && length($encoded) > 1) {
my @octets = split //, $encoded;
shift @octets;
$continuation_octets{$_}++ for @octets;
}
}
}https://stackoverflow.com/questions/57278902
复制相似问题