如何在Perl中选择一行的部分?

时间:2011-05-27 18:38:15

标签: perl

我有很多长文件,但我只对每个文件的部分信息感兴趣。到目前为止,我有一个修剪文件的代码,并为我提供包含我需要的信息的行,当时正在处理一个文件。

这是我正在使用的代码:

 #!/usr/bin/perl
use strict;
use warnings;
my $data;

open FILE, "<$ARGV[0]" or die "cannot open file '$ARGV[0]'!\n\n";

while ($data= <FILE>){
    chomp $data;

    if( $data=~m/\<input type="hidden" name="description" value="454read"><input type="hidden" name="format" value="fasta"><input type="submit" name="submitbutton" value="FASTA"/)
    {
        $data=~s/[^ACTGN]//g;
        print $data;
    }
}

这是我得到的输入:

 <input type="hidden" name="sequence" value="TTGTTGAGCTCGACGGTCATGACCCAGCTGGAGTCGGCACGGGCACCCGCGCGCTTCTGCCAGACGCCAATGTGGGACTTCTCGGTGTCGAGGC"><input type="hidden" name="name" value="FUY784js_7HL"><input type="hidden" name="description" value="454read"><input type="hidden" name="format" value="fasta"><input type="submit" name="submitbutton" value="FASTA">

由此我只需要两个部分,TTGTT .... AGGC,这部分将始终为大写A,T,C,G或N,但每个文件的长度可能不同。我还需要为此保存名称,在这种情况下为FUY784js_7HL,此名称每次都会更改。

理想输出应如下所示:

FUY784js_7HL
TTGTTGAGCTCGACGGTCATGACCCAGCTGGAGTCGGCACGGGCACCCGCGCGCTTCTGCCAGACGCCAATGTGGGACTTCTCGGTGTCGAGGC

你知道我该怎么做吗?我有很多像这样的文件。如果你们中的任何一个人能帮助我弄清楚如何让它适用于多个文件,我将不胜感激。

谢谢!

3 个答案:

答案 0 :(得分:1)

perl -pe 's/[^ACTGN]//g;'

作为看似有问题的位的代理,上述命令似乎起作用,至少对于以<input和第二个输出行开头的输入行。

如果你的真实节目中没有任何其他版画,我不确定它是如何产生你所说的那样。

实际上,这是谎言。我得到了:

TTGTTGAGCTCGACGGTCATGACCCAGCTGGAGTCGGCACGGGCACCCGCGCGCTTCTGCCAGACGCCAATGTGGGACTTCTCGGTGTCGAGGCATA

因为最后的FASTA值而退回。如果要限制为主值:

perl -pe 's/.*"([ACTGN]+)".*<input\b[^>]*\bname="name"\s[^>]*\bvalue="([^"]+)".*/$2\n$1/;'

请注意,所有关于使用正则表达式解析XML的愚蠢和脆弱性的标准免责声明均适用。具体来说,重新排序名称和值属性是完全合法的,这个示例正则表达式不允许这样做。

答案 1 :(得分:0)

如果我正确理解了问题,那么使用捕获组就可以满足您的需求。特别是因为你知道开头和结尾,但不知道中间,这样的事情应该有效:

$data =~ /TTGTT(.+)AGGC/;
print $1;

查看perldoc上捕获组的部分: http://perldoc.perl.org/perlre.html#Regular-Expressions

答案 2 :(得分:0)

从发布的内容来看,我认为这将返回序列:

$data =~ /name="sequence" value="([AGCT]*).*name="name" value="([^"])"/;
print "$2\n$1";