我有这段代码:
if ($line =~ /gene_id "([A-Za-z0-9:._]*)";/) {
$chromosome{$1} = $chompline[0];
push @{$starts{$1}}, $chompline[3];
push @{$ends{$1}}, $chompline[4];
$strand{$1} = $chompline[6];
$geneid = $1;
$line =~ /;transcript_id "([A-Za-z0-9:._]*)";/;
$transcriptid = $1;
}
此代码读取以下文件:
scaffold_1 Cufflinks exon 40478 40618 . + . gene_id "ppa023343m.g";transcript_id "PAC:17657390";tss_id "TSS1"
scaffold_1 Cufflinks exon 40723 40832 . + . gene_id "ppa023343m.g";transcript_id "PAC:17657390";tss_id "TSS1"
scaffold_1 Cufflinks exon 40944 41016 . + . gene_id "ppa023343m.g";transcript_id "PAC:17657390";tss_id "TSS1"
scaffold_1 Cufflinks exon 41667 41728 . + . gene_id "ppa023343m.g";transcript_id "PAC:17657390";tss_id "TSS1"
scaffold_1 Cufflinks exon 42268 42585 . - . gene_id "ppa017353m.g";transcript_id "PAC:17642447";tss_id "TSS3451"
scaffold_1 Cufflinks exon 43369 43510 . + . gene_id "ppa023343m.g";transcript_id "PAC:17657390";tss_id "TSS1"
scaffold_1 Cufflinks exon 44834 45052 . + . gene_id "ppa023343m.g";transcript_id "PAC:17657390";tss_id "TSS1"
scaffold_1 Cufflinks exon 45195 45261 . + . gene_id "ppa023343m.g";transcript_id "PAC:17657390";tss_id "TSS1"
scaffold_1 Cufflinks exon 47061 47460 . + . gene_id "ppa023343m.g";transcript_id "PAC:17657390";tss_id "TSS1"
scaffold_1 Cufflinks exon 49006 49153 . + . gene_id "ppa023343m.g";transcript_id "PAC:17657390";tss_id "TSS1"
并且代码适用于除了以下所有行之外的所有行:
scaffold_2 Cufflinks exon 16897769 16898166 . - . gene_id "ppa018337m.g";transcript_id "PAC:17646596_o.3";tss_id "TSS10299"
scaffold_2 Cufflinks exon 16899376 16899536 . - . gene_id "ppa018337m.g";transcript_id "PAC:17646596_o.3";tss_id "TSS10299"
例如,我想要以下输出:
ppa023343m.g PAC:17657390
除了我向你展示过的那些线外,它一直都在发生......如果是这些线,我会得到以下结果:
PAC:17646596_o.3 PAC:17646596
这怎么可能?
答案 0 :(得分:1)
在你的第二个正则表达式中,你说:
$line =~ /;transcript_id "([A-Za-z0-9:._]*)";/;
您允许从a
到z
和A
到Z
的字符以及所有数字,冒号:
,点.
并强调_
。你的台词有这个东西:
transcript_id "PAC:17646596_o.3";
transcript_id "PAC:17646596_o.3";
正则表达式中你角色组中的所有内容都在那里,所以它们匹配。有下划线和点,还有更多的字母和数字。您的代码完全按照您的要求执行。
也许这种解释可以帮助您更好地理解它:http://regex101.com/r/dE9hJ3
如果您不想在输出中使用_o.3
,请将正则表达式更改为:
$line =~ /;transcript_id "([A-Za-z0-9:]*)[^"]*";/;
# ^
# notice the ) here ends the capture group
答案 1 :(得分:0)
在使用捕获的变量之前,始终验证正则表达式是否成功。
$transcriptid = $line =~ /;transcript_id "([\w:.]*)";/
? $1
: warn "transcript_id didn't match: $line";
或者,您也可以将正则表达式匹配加入到单个语句中,因此只需要进行一次错误检查:
if ($line =~ /gene_id "([\w:.]*)";transcript_id "([\w:.]*)";/) {
($geneid, $transcriptid) = ($1, $2);
$chromosome{$geneid} = $chompline[0];
push @{$starts{$geneid}}, $chompline[3];
push @{$ends{$geneid}}, $chompline[4];
$strand{$geneid} = $chompline[6];
} else {
warn "Regex didn't match: $line\n"
}
答案 2 :(得分:-1)
您需要转义句点等字符,否则它将匹配任何内容。另外,让单个正则表达式捕获两个数据(根据您发布的代码而不知道您的意图是什么)更有意义:
if ($line =~ /gene_id "([^\"]*)";transcript\_id\s\"(PAC:[^\"]*)\"/ ) {
$geneid = $1;
$transcriptid = $2;
}
编辑:链接到正则表达式演示:http://regex101.com/r/wK1gF8