作为这个问题的背景,我应该解释一下,我不懂任何Perl,并且对正则表达式过敏(我们都有弱点(。我正试图弄清楚为什么Perl程序不接受我输入的数据。我不需要深入了解这个程序——我只是在做时间比较。
考虑一下这个赋值语句:
($sample_ls_id) = $sample_ls_id =~ /:ww(d+):/;
如果我理解正确的话,它就是检查sample_ls_id
是否与某个正则表达式匹配,如果匹配,则分配整个字符串,或者类似的东西。
然而,我不明白这是怎么回事。根据文件,即perldoc perlretut
,我简要查看了
$sample_ls_id =~ /:ww(d+):/
如果匹配,只返回true或false。
我试图匹配的字符串看起来像
1000 10 0 0 1 urn:lsid:dcc.hapmap.org:Individual:CEPH1000.10:1 urn:lsid:dcc.hapmap.org:Sample:SAMPLE1:1
此操作失败,出现错误
Use of uninitialized value $sample_ls_id in concatenation (.) or string
at database/populate/family.pl line 38, <INPUT> line 1.
第38行为
print OUTPUT "$sample_ls_idt$family_ped_idt$individual_ped_idt$father_ped_idt$mother_ped_idt$sext$created_byt$population_coden";
请参阅下面的完整脚本。然而,显然非常相似的字符串
1420 9 0 0 1 urn:lsid:dcc.hapmap.org:Individual:CEPH1420.09:1 urn:lsid:dcc.hapmap.org:Sample:NA12003:1
似乎通过了。
就上下文而言,整段代码是:
use strict;
use warnings;
use Getopt::Long;
my $input_file = "data/family_ceu.txt";
my $output_file = "sql/family_ceu.sql";
my $population_code = "CEU";
GetOptions ('i=s' => $input_file,
'o=s' => $output_file,
'p=s' => $population_code
);
usagecheck();
my $created_by = 'gwas_analyzer';
print "Creating SQL file for inserting family data from $input_filen";
open (INPUT, "< $input_file");
open (OUTPUT, "> $output_file");
print OUTPUT "INSERT INTO population (population_code, private) VALUES ('$population_code', 'f');n";
print OUTPUT "COPY family (ls_id, family_ped_id, individual_ped_id, father_ped_id, mother_ped_id, sex, created_by, population_code) FROM stdin;
";
while (my $line = <INPUT>)
{
chomp $line;
#Skip any comment lines
next if($line =~ /^#/);
my ($family_ped_id, $individual_ped_id, $father_ped_id, $mother_ped_id, $sex, $individual_ls_id, $sample_ls_id) = split (/t/, $line);
($sample_ls_id) = $sample_ls_id =~ /:ww(d+):/;
print OUTPUT "$sample_ls_idt$family_ped_idt$individual_ped_idt$father_ped_idt$mother_ped_idt$sext$created_byt$population_coden";
}
print OUTPUT "\.n";
close OUTPUT;
sub usagecheck
{
if (!$input_file || !$output_file || !$population_code)
{
print "Missing argument (see required arguments below):n";
usage();
exit;
}
}
sub usage
{
print "perl family.pl -i <input file> -o <output file> -p <population code>n";
}
如果你知道正则表达式和Perl,我相信这是一个非常简单的问题。
当$sample_ls_id = 'urn:lsid:dcc.hapmap.org:Sample:SAMPLE1:1';
正则表达式"/:\w\w(\d+(:/;"失败。当字符串后面有冒号":"one_answers"word"字符"\w"时,此正则表达式将通过,另一个"单词"字符'\w',后跟一个或多个数字'\d+'和冒号':'。
当$sample_ls_id = 'urn:lsid:dcc.hapmap.org:Sample:NA12003:1';
正则表达式"/:\w\w(\d+(:/;"在中找到匹配项':NA12003:'。(冒号、2个单词字符、数字和一个冒号(。
my $sample_id = 'urn:lsid:dcc.hapmap.org:Sample:NA12003:1'
($sample_ls_id) = $sample_ls_id =~ /:ww(d+):/;
"($sample_ls_id("捕获匹配的"(\d+("部分(也存储在$1中(,在本例中为12003。
您在前面的示例中遇到了一个错误,因为正则表达式失败并且未定义"($sample_ls_id("。
在列表上下文中,例如对($sample_ls_id)
的赋值,=~
返回捕获的列表。它可以将提取$1
等保存在一个单独的语句中。
与其将字符串本身存储回自身,不如使用捕获。\d由1美元持有,所以只需将代码更改为这样的代码:
$sample_ls_id =~ /:ww(d+):/; # no letters before implies "match"
$sample_ls_id = $1; # I assume that $1 will be empty if no match, I'm not 100% on this.
我不知道你为什么会出现这样的错误,但你的代码似乎会像上面一样更有意义。
这可能与输入没有最后一个元素有关(例如,您有A:B:C,但您需要A:B:C:D将D存储在示例ls-id中,如果D丢失,则它永远不会初始化,然后regex就没有意义了。(
此外,我们没有所有的代码(第38行看起来与while循环中的第一行相对应(,如果你发布更多可能会有所帮助。