Chinaunix首页 | 论坛 | 博客
  • 博客访问: 313112
  • 博文数量: 174
  • 博客积分: 3061
  • 博客等级: 中校
  • 技术积分: 1740
  • 用 户 组: 普通用户
  • 注册时间: 2006-05-04 22:43
文章分类

全部博文(174)

文章存档

2011年(54)

2010年(14)

2009年(30)

2008年(26)

2007年(27)

2006年(23)

我的朋友

分类: WINDOWS

2007-05-17 16:24:40

今天处理perl的中文字符处理,发现了有如下现象.

1. 源文件中直接引用的字符,那么将按照文本本来的存储方式存储,比如  ex.pl 文件中定义了

   my $val = "新建文件夹";

 而ex.pl 被存储为ANSI格式. 那么 "新建文件夹"也是以此种方式编码.

  这样的话,UTF-8,unicode等也可类推.

2. 源文件中读入的字符. 比如
    my $val = ;
   那么将依赖于当前所处于的 编码方式,如果是936 codepage也就是简体中文.
   那么val将存储为cp936 方式.gbk/gb2312.

3. use utf8; 选项
   此选项表示此作用域下的字符串,perl在内部以utf8进行存储,因此在此种情况下,
   my $val = "新建文件夹"; 有可能导致问题,如果ex.pl以utf8不兼容格式存储,比如多字节存储 。

4. 默认console的输入得到的是什么? 我在调试中发现,实际上选择默认,或者所谓的ANSI来存储中文,
   实际上是以多字节MBCS来进行存储,也就是说以当前codepage的编码方式来存储的.

5. 今天碰到的问题就是
    open my $fh, '>:encoding(utf-8)', $filename or die "open($filename): $!";   
    XMLout($data, OutputFile => $fh ,  RootName => "component" , XMLDecl => "");
    close($fh);

为什么将中文写出了乱码?
这个实际上是 >:encoding(utf-8)的实现不是我们所想的执行了类似Encode::from_to($val,"cp936","utf8") or die "error";  从结果看,似乎是将每个自己都扩展了一倍,比如 0xd0 => 0xd0 0x00 .这样C936的编码,就变得乱七八糟.

 

6. perl内部存储格式和直接utf-8格式的区别.

   perl的内部格式是以unicde形式存储的. 而utf-8还是以字节流形式存在的. 看下面的例子.

    $str = utf8("骆驼");  # 假设文件是以utf-8存储的

    print length($str) ;  将会 = 6 ,因为utf-8编码的字节流就是6个字节

$str=    decode("utf-8",$str);  # perl内部格式,unicode,

    print length($str);  # = 2

{

  use bytes;

  print length($str); # 6 字节流形式

}

 

7. unicode::string 的用法.

   此包,能够将指定的输入字符转化为其它表述格式.

 

  $u = utf8("骆驼");  # 文件以utf-8存储

  print length($u->utf8); # 6

   

 

2007-07-26

假如 open $fh , <:encoding(utf-8)",$filename 这种方式,那么不需要在

$line = <$fh> 后使用$line = decode ("utf-8",$line); 否则需要decoding.

也就是说在打开文件的时候如果指定格式,那么perl将自动帮你将读入的格式转换为内部格式.

另外带有格式的文件往往开头有bom字节,比如一个文件开始

to : ,那么使用

$line =~ m/\s*to/i ; 是无法匹配的,需要用

$line =~ m/\W*to/i ; 来匹配,也就是说允许to之前出任意个不可见字符.

 

假如你已经知道了当前的字符串格式是perl的内部格式,那么如果你要打印到目前的console上,比如console是 cp936的,那么打印就是出现乱码.

这种情况下:

$internaldata;

$cp936data = encode("cp936" , $internaldata);

print $cp936data,"\n";

这样就能够显示正确的中文.


阅读(910) | 评论(0) | 转发(0) |
0

上一篇:subversion idea!

下一篇:perl-gtk

给主人留下些什么吧!~~