我有一段代码:
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那件事怎么可能?
发布于 2014-05-09 00:57:12
在您的第二个正则表达式中,您会说:
$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发布于 2014-05-09 03:20:59
在使用捕获的变量之前,请始终验证正则表达式是否成功。
$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"
}发布于 2014-05-09 01:05:17
您需要转义诸如句点之类的字符,否则它将匹配任何字符。此外,让单个正则表达式捕获这两部分数据(基于您发布的代码,并且不知道您的意图)也更有意义:
if ($line =~ /gene_id "([^\"]*)";transcript\_id\s\"(PAC:[^\"]*)\"/ ) {
$geneid = $1;
$transcriptid = $2;
}编辑:正则表达式演示链接:http://regex101.com/r/wK1gF8
https://stackoverflow.com/questions/23547835
复制相似问题