【问题标题】:perl's split function not working properly for UTF-16 encodingperl 的 split 函数在 UTF-16 编码中不能正常工作
【发布时间】:2016-12-05 19:55:57
【问题描述】:

问题:为什么最后没有 CFLF 的最后一行没有被 perl 的 split 函数正确拆分。它应该显示 5 个字段。

输入文件有这些行。最后一行没有 CRLF(回车和换行)

1;P7;extended ascii ÀÇÊ;;
2;P8;non-ascii ΩЖאഉて;;
3;P8;non-ascii ΩЖאഉて;;

我的代码是,

use strict;
use warnings;
use Encode;
use utf8;
my $COL_SEP=';';
open FL, "<:encoding(UTF-16)", $ARGV[0] or die "canot open\n";
while(my $line= <FL>) {
chomp $line;
    print "$. length=",length($line),"\n";
#   print "\n",$line,"\n";
    my @fields = split($COL_SEP, $line);
    print "number of fields=",scalar(@fields),"\n";
}
close FL;

输出是

1 length=26
number of fields=5
2 length=23
number of fields=5
3 length=22
number of fields=3

【问题讨论】:

    标签: perl encoding split utf-16


    【解决方案1】:

    对于第一行,split 返回"1", "P7", "extended ascii ÀÇÊ", "", "\r"

    对于第二行,split 返回"2", "P8", "non-ascii ΩЖאഉて", "", "\r"

    对于第三行,split 将返回 "3", "P8", "non-ascii ΩЖאഉて", "", "",但 split 默认会删除空的尾随字段。

    问题 1:行终止符删除不当。

    改变

    open(FL, "<:encoding(UTF-16)", $ARGV[0])
    

    open(FL, "<:encoding(UTF-16):crlf", $ARGV[0])
    

    如果你希望它也能在 Windows 上正常工作,那需要

    open(FL, "<:raw:encoding(UTF-16):crlf", $ARGV[0])
    

    当然,你不应该使用全局变量,所以真的应该这样

    open(my $FL, "<:raw:encoding(UTF-16):crlf", $ARGV[0])
    

    问题 2:保留空尾随字段。

    改变

    my @fields = split($COL_SEP, $line);
    

    my @fields = split($COL_SEP, $line, -1);
    

    当然,split 的第一个参数应该是一个正则表达式模式,所以应该是这样

    my @fields = split(quotemeta($COL_SEP), $line, -1);
    

    my @fields = split(qr/\Q$COL_SEP/, $line, -1);
    

    my @fields = split(/\Q$COL_SEP/, $line, -1);
    

    【讨论】:

    • 太棒了!这解决了我的问题:) 另外我不知道 1) 如果最后一个字段为空,则拆分修剪最后一个字段。教育这个请链接。 2) "<:raw:encoding>
    • 最好的做法是使用 -1 和 split 吗?我的@fields = split($COL_SEP, $line, -1);
    • 1) split。 /// 2) :raw 基本上是 binmode,没有第二个参数。在这种情况下,它会阻止在 :encoding 之前添加 :crlf(Perl 在 Windows 上所做的事情)。你已经知道:encoding:crlf 导致读取时 CRLF=>LF 和写入时 LF=>CRLF。 /// 3) 这一切都取决于你想要什么。通常,我要么想要-1,要么没关系。
    猜你喜欢
    • 1970-01-01
    • 2019-03-05
    • 2015-04-28
    • 1970-01-01
    • 2012-04-17
    • 2012-03-13
    • 2013-12-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多