我正在将我们大学中国研究系古老的基于DOS的图书馆程序生成的文件转换为更有用和可访问的内容.
我正在处理的问题之一是导出的文本文件(大小约为80MB)采用混合编码.我在Windows上.
德语变音符号和其他高位ASCII字符用cp1252编码,我认为是GB18030中的CJK字符.由于"重叠"编码,我不能将整个文件拖到Word或其他东西并让它进行转换,因为我会得到这样的东西:
原稿:
+Autor:
-Yan, Lianke / ÑÖÁ¬¿Æ # encoded Chinese characters
+Co-Autor:
-Min, Jie / (šbers.) # encoded German U-umlaut (Ü)
Run Code Online (Sandbox Code Playgroud)
结果:
+Autor:
-Yan, Lianke / ??? # good
+Co-Autor:
-Min, Jie / (?ers.) # bad... (should be: "Übers.")
Run Code Online (Sandbox Code Playgroud)
所以我编写了一个带有几个子程序的脚本,这些子程序分几步转换非ASCII字符.它做了以下事情(其中包括):
用字母数字代码替换一些高阶ASCII字符(š,á等)(不太可能自然地出现在文件中的任何其他位置).例如:-Min, Jie / (šbers.)- > -Min, Jie / (uumlautgrossbers.)
注意:我手工完成了"转换表",所以我只考虑了实际出现在我文档中的特殊字符.因此,转换并不完全,但在我的案例中产生了足够的结果,因为我们的书籍主要是德语,英语和中文,只有很少的语言,如意大利语,西班牙语,法语等,而且几乎没有捷克语等.
仅当á, £, ¢, ¡, í字母数字代码不在高ASCII范围内的其他字符之前或之后时,才\x80-\xFF替换它们.(这些是ß, ú, ó, í和" small nordic o with cross-stroke" 的cp1252编码版本,并且出现在cp1252和GB18030编码的字符串中.)
读取整个文件并将其从GB18030转换为UTF8,从而转换为真实汉字的编码汉字.
将字母数字代码转换回其Unicode等效代码. …
更新2:解决了.见下文.
我正在将一个大的txt文件从旧的基于DOS的库程序转换为更有用的格式.我刚开始使用Perl并设法将这样的脚本放在一起:
BEGIN {undef $/; };
open $in, '<', "orig.txt" or die "Can't read old file: $!";
open $out, '>', "mod.txt" or die "Can't write new file: $!";
while( <$in> )
{
$C=s/foo/bar/gm;
print "$C matches replaced.\n"
etc...
print $out $_;
}
close $out;
Run Code Online (Sandbox Code Playgroud)
这是相当快的,但经过一段时间后,我总是得到一个"Out of Memory" - 由于缺少RAM/Swap-Space而导致的错误(我在Win XP上使用2GB的Ram和1.5GB的Swap-File).在看了一下如何处理大文件后,File::Map在我看来这是一个避免这个问题的好方法.但是,我在实施它时遇到了麻烦.这就是我现在所拥有的:
#!perl -w
use strict;
use warnings;
use File::Map qw(map_file);
my $out = 'output.txt';
map_file my $map, 'input.txt', '<';
$map =~ s/foo/bar/gm;
print $out $map;
Run Code Online (Sandbox Code Playgroud)
但是我收到以下错误: Modification of a …