【问题标题】:Remove special character while reading file in perl在perl中读取文件时删除特殊字符
【发布时间】:2021-05-01 06:09:50
【问题描述】:

我有一个 Excel 表 (Test.xls),其中包含以下内容:

Name,account,flat Number,city
A,111111,1352†,XXXX
B,222222,2352†,YYYY
C,333333,3352†,YYYY

第 3 列中的特殊字符为 †。

当我使用 perl 5.12.5 版本运行 Perl 脚本 a.pl 时出现以下错误。

在 test.pl 第 2 行打印宽字符。

但是当我使用 Perl 5.6.1 版本执行相同的脚本时,我们没有收到此错误。

请有人指导如何在通过 parseexcel 模块读取 excel 表的内容时忽略/删除此特殊字符。

虽然 Perl 5.6.1,为什么这个特殊字符在通过 parseexcel 模块获取文件内容时被忽略了。

    #!/Volumes/app/perl/5.12/bin/perl -w
    use Spreadsheet::ParseExcel;

    my $srce_file = "a.xls"; 
    my $oExcel = new Spreadsheet::ParseExcel;
    my $oBook = $oExcel->Parse($srce_file); 
    my %hah_sheet = ();
    my $header_row  = 1;
        my($iR, $iC, $oWkS, $oWkC);
        my $book = $oBook->{File};
        my $nsheet= $oBook->{SheetCount};
        my $author= $oBook->{Author};
        unless($nsheet){
            print "ERR>No worksheet found for source file:$srce_file\n";
            return 0;
        }
        else{
            print "INFO>Excel                         
           File=$srce_file,#WorkSheet=$nsheet,AuthorID=$author\n";
        }


   for(my $iSheet=0; $iSheet < $oBook->{SheetCount} ; $iSheet++) {
    next if($iSheet >0);    
    $oWkS = $oBook->{Worksheet}[$iSheet];

    my $rows = 0;
    for(my $iR = $oWkS->{MinRow}; defined $oWkS->{MaxRow} && $iR <= $oWkS->{MaxRow} ; $iR++) {
        $rows++;

        my $str_len = 0;
        for(my $iC = $oWkS->{MinCol}; defined $oWkS->{MaxCol} && $iC <= $oWkS->{MaxCol}; $iC++) {
            $oWkC = $oWkS->{Cells}[$iR][$iC];
            next if ($iR <$header_row);
            
            if (defined($oWkC)){
                my $cell_value = $oWkC->Value;
                $cell_value =~s/\n+//g;               #removed newline inside the value
                #
                ##if the first column at header row is null then skip. Column might be shifted
                if($iR==$header_row && $iC == 0){
                    last unless($cell_value);
                }
                if($iR == $header_row){
                   $hah_sheet{$iR}{$iC} = uc($cell_value);
                }else {
                   $hah_sheet{$iR}{$iC} = $cell_value;
                   $str_len += length($cell_value);  
                   ##View cell value by row/column
                   print "DEBUG>row ${iR} - col ${iC}:$cell_value\n";
                }
            }else{
                $hah_sheet{$iR}{$iC} = "";              #keep position for NULL value
            }
        } # END of Column loop
    } # END of Row loop
} # END of Worksheet
      

使用 perl 5.12 版本输出:

INFO>Excel File=a.xls,#WorkSheet=1,AuthorID=
DEBUG>row 2 - col 0:Name
DEBUG>row 2 - col 1:account
DEBUG>row 2 - col 2:flat Number
DEBUG>row 2 - col 3:city
DEBUG>row 3 - col 0:A
DEBUG>row 3 - col 1:111111
Wide character in print at ./a4_test.pl line 49.
DEBUG>row 3 - col 2:1352†
DEBUG>row 3 - col 3:XXXX
DEBUG>row 4 - col 0:B
DEBUG>row 4 - col 1:222222
Wide character in print at ./a4_test.pl line 49.
DEBUG>row 4 - col 2:2352†
DEBUG>row 4 - col 3:YYYY
DEBUG>row 5 - col 0:C
DEBUG>row 5 - col 1:333333
Wide character in print at ./a4_test.pl line 49.
DEBUG>row 5 - col 2:3352†
DEBUG>row 5 - col 3:YYYY

perl 5.6.1 版本的输出:-

INFO>Excel File=a.xls,#WorkSheet=1,AuthorID=
DEBUG>row 2 - col 0:Name
DEBUG>row 2 - col 1:account
DEBUG>row 2 - col 2:flat Number
DEBUG>row 2 - col 3:city
DEBUG>row 3 - col 0:A
DEBUG>row 3 - col 1:111111
DEBUG>row 3 - col 2:1352
DEBUG>row 3 - col 3:XXXX
DEBUG>row 4 - col 0:B
DEBUG>row 4 - col 1:222222
DEBUG>row 4 - col 2:2352
DEBUG>row 4 - col 3:YYYY
DEBUG>row 5 - col 0:C
DEBUG>row 5 - col 1:333333
DEBUG>row 5 - col 2:3352
DEBUG>row 5 - col 3:YYYY

【问题讨论】:

标签: perl utf-8 solaris


【解决方案1】:

我对您的数据或其含义一无所知,但我通常反对更改数据以消除编程警告。如果 v5.6 版本有效但 v5.12 无效,您可能希望保留数据。 (而且,5.6 是古老的,是 Perl 第一次处理 Unicode 的一部分。我们没有正确地做很多事情,也没有识别和警告我们应该遇到的所有情况。现在我们知道更多,所以你会收到警告已经成为问题的东西)。

这个特殊的警告告诉你你没有告诉 Perl 如何编码输出,它试图打印一个“宽”(多于一个八位字节)字符。这通常意味着输出的形式可能不是目标所期望的(参见mojibake)。

假设您想要 UTF-8 输出,一个快速的解决方法是告诉 Perl 将其标准文件句柄编码为 UTF-8。一种常见的方法是通过open pragma:

use open ':std', ':encoding(UTF-8)';

Learning Perl 最新版本的末尾有一个关于 Unicode 的入门以及正确处理它需要做的各种事情。


但是假设您不想要(除了没有收到警告之外,您还有充分的理由这样做)。使用可以使用 Perl 的普通文本操作功能,比如替换运算符:

use utf8;  # tell Perl source is UTF-8
$column =~ s/†//g;

或者,如果您不想输入文字字符,您可以通过代码编号指定它:

$column =~ s/\x{2020}//; # goodbye 2020

【讨论】:

  • 我已经更新了我的问题本身的代码和共享输出,同时使用 diff perl 版本运行相同的 perl 脚本
猜你喜欢
  • 2013-07-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-04
  • 2016-10-17
  • 1970-01-01
相关资源
最近更新 更多