【发布时间】:2014-07-26 19:51:53
【问题描述】:
我目前正在使用 Perl 和模块 Text::CSV 从 CSV 文件中提取文本。
每个 CSV 文件都有引号分隔每个字段。文本被保存到独立的文本文件中,标签分隔成列。我可以从文本文件中调用和打印每一列没有问题,但是当我尝试在循环中使用这些值时,我收到错误Unrecognized character \xEF。
我的代码示例如下:
#!/usr/bin/perl
use strict;
use warnings;
use Text::CSV;
#### Match ligand data with GPCR interaction data ####
my $csv = Text::CSV->new();
my $file = $ARGV[0];
open (FILE, "<$file");
open (OUT, ">new_$file");
while (my $line2 = <FILE>)
{
binmode(STDOUT, ":utf8");
if ($line2 =~ /^(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)$/)
{
#### Data from filtered1.txt ####
my $up_fil = $1;
my $ligid_fil = $2;
my $units_fil = $3;
my $low_fil = $4;
my $median_fil = $5;
my $upper_fil = $6;
my $ref = $7;
#### Convert negative log affinity values to normal ####
my $activity = $units_fil;
$activity =~ s/p//;
my $value;
if ($median_fil ne "")
{
$value = $median_fil;
$value = (10**-$median_fil)/(10**-9);
}
elsif ($low_fil ne "" and $upper_fil ne "")
{
my $lower = $low_fil;
$lower = (10**-$low_fil)/(10**-9);
my $upper = $upper_fil;
$upper = (10**-$upper_fil)/(10**-9);
$value = "$upper - $lower";
}
else
{
$value = "n/a";
}
#### Match entries from filtered1.txt with ligands.csv ####
open (LIG, "<ligands.csv");
while (my $line3 = <LIG>)
{
$csv->parse($line3);
my @ligand_fields = $csv->fields();
if (!$ligand_fields[14]) { next; }
if ($ligand_fields[0] eq $ligid_fil)
{
#print OUT "$ligand_fields[14]\t$ligand_fields[13]\t$up_fil\t$ligid_fil\t$activity\t$value\t$ref\n";
print "$ligand_fields[14]\t$ligand_fields[13]\t$up_fil\t$ligid_fil\t$activity\t$value\t$ref\n";
next;
}
}
close LIG;
}
}
close FILE;
close OUT;
我也尝试过按照以下方式使用正则表达式,但无济于事。
# remove BOM
${$self->{CODE}} =~ s/^(?:
\xef\xbb\xbf |
\xfe\xff |
\xff\xfe |
\x00\x00\xfe\xff |
\xff\xfe\x00\x00
)//x;
原始 CSV 文件似乎没有任何 BOM,因此我怀疑 Text::CSV 可能在解析和返回值时创建它。我希望这是对问题的足够清楚的解释,如果需要,我可以提供更多细节。提前感谢您提供的任何建议。
【问题讨论】:
-
您读取编码字节,然后告诉 STDOUT 它们是要转换为 UTF-8 的 Unicode 代码点。解码您的输入文件以获得 Unicode 代码点!
-
感谢您的编辑,米勒。另一方面,我发现出了什么问题。原来 if 和($median_fil ne "") 之间有一个奇怪的类似空格的字符,导致错误。我删除了空间,添加了一个新空间,瞧,错误消失了。无论如何,感谢您的帮助!
标签: perl csv byte-order-mark