обновление файла Unicode дает мне китайские символы - PullRequest
1 голос
/ 26 января 2012

У меня есть файл "Application.config", который представляет собой файл Unicode (в отличие от ANSI или UTF8), который содержит что-то вроде

...
<GENERAL>
            ...
    <FULLVERSION>18.0.13.227</FULLVERSION>
</GENERAL>
...

Следующий скрипт должен изменить это значение на 18.1.00.012 и сделал это на 32-битной Perl / OS:

my ($Company, $Config);

$Company=$ENV{ProgramData}."\\Sage\\Accounts\\2012\\Application.config";
if( -f  $Company)
{
  $Config='';
  if(open(APPCONF, "<".$Company))
  {
    while(<APPCONF>)
    {
      $Config.=$_;
    }
    close(APPCONF);
  }
  if($Config=~s/(<.F.U.L.L.V.E.R.S.I.O.N.>.).*?(<.\/.F.U.L.L.V.E.R.S.I.O.N.>.)/\1\xfa\2/mi)
  {
    $Config=~s/\xfa/1\x008\x00\.\x000\x001\.\x000\x000\x00\.\x000\x001\x002\x00/mi;
    if(open(APPCONF, ">".$Company))
    {
      binmode(APPCONF);
      print APPCONF $Config;
      close APPCONF;
    }
  }
}

Что происходит (на 64-битном Perl): «FULLVERSION» выглядит нормально, но «/ FULLVERSION» полностью искажено и выглядит как китайский.

Может кто-нибудь помочь?

Пит

Ответы [ 2 ]

3 голосов
/ 26 января 2012
use autodie qw(:all);
use IO::File qw();
require File::BOM;
my $Company = $ENV{ProgramData} . "\\Sage\\Accounts\\2012\\Application.config";

# File::Slurp apparently is buggy with PerlIO, no time to investigate.
# Let's read/write files the normal way.
my $Config = do {
    open my $appconf, '<:via(File::BOM)', $Company;
    join q(), $appconf->getlines;
};

$Config =~ s|
    (?<= <FULLVERSION> )
    .*
    (?= </FULLVERSION> )
    |18.1.0.012|msx;

{
    open my $appconf, '>:encoding(UTF-16LE):via(File::BOM)', $Company;
    $appconf->print($Config);
}

Еще лучше, не искажайте XML с помощью регулярных выражений, вместо этого используйте XML-модуль .Они также понимают UTF-16.




hexdump Application.bad_2.config

0000:0170 | 09 00 3C 00  46 00 55 00  4C 00 4C 00  56 00 45 00 | ..<.F.U.L.L.V.E.
0000:0180 | 52 00 53 00  49 00 4F 00  4E 00 3E 00  31 00 38 00 | R.S.I.O.N.>.1.8.
0000:0190 | 2E 00 30 00  31 2E 00 30  00 30 00 2E  00 30 00 31 | ..0.1..0.0...0.1
0000:01A0 | 00 32 00 3C  00 2F 00 46  00 55 00 4C  00 4C 00 56 | .2.<./.F.U.L.L.V
0000:01B0 | 00 45 00 52  00 53 00 49  00 4F 00 4E  00 3E 00 0D | .E.R.S.I.O.N.>..
0000:01C0 | 00 0A 00 09  00 3C 00 2F  00 47 00 45  00 4E 00 45 | .....<./.G.E.N.E
2 голосов
/ 26 января 2012

Обратите внимание, что вы вставили нечетное количество байтов. Это сдвигает все байты и делает младшие байты старшими, и наоборот. В частности, по смещению 0x0194 у вас есть 31 2E 00 вместо 31 00 2E 00.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...