Как выделить части строки в Perl?

#perl

#perl

Вопрос:

У меня много длинных файлов, но меня интересует только часть информации о каждом из них. На данный момент у меня есть код, который обрезает файл и выдает мне строку, содержащую нужную мне информацию, обрабатывая по одному файлу за раз.

Это код, который я использую:

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

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

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….Кроме того, эта часть всегда будет заглавной A,T,C,G или N, однако длина может отличаться в каждом файле. Мне также нужно сохранить для этого имя, которое в данном случае является FUY784js_7HL, это имя будет меняться каждый раз.

Идеальный вывод должен выглядеть следующим образом:

 FUY784js_7HL
TTGTTGAGCTCGACGGTCATGACCCAGCTGGAGTCGGCACGGGCACCCGCGCGCTTCTGCCAGACGCCAATGTGGGACTTCTCGGTGTCGAGGC
  

У вас есть какие-либо идеи о том, как я могу это сделать? У меня есть много файлов, подобных этому. Я буду признателен, если кто-нибудь из вас сможет помочь мне разобраться, как заставить это работать для нескольких файлов.

Спасибо!

Комментарии:

1. Было бы полезно иметь пример ввода

Ответ №1:

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

В качестве прокси для бита, который кажется проблематичным, приведенная выше команда, похоже, работает, по крайней мере, со строкой ввода, начинающейся с <input , и со второй строкой вывода.

Если у вас нет других отпечатков в вашей реальной программе, я не уверен, как она могла бы создать строку, о которой вы сказали.

На самом деле, это была ложь. Я получил:

TTGTTGAGCTCGACGGTCATGACCCAGCTGGAGTCGGCACGGGCACCCCGCGCTTCTGCCAGACGCCAATGTGGGACTTTCTCGGTGTCAGGCATA

назад из-за значения FASTA в конце. Если вы хотите ограничить основное значение:

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

Пожалуйста, обратите внимание, что применяются все стандартные заявления об отказе от ответственности по поводу глупости и хрупкости синтаксического анализа XML с помощью регулярного выражения. В частности, совершенно законно изменять порядок атрибутов name и value, а это примерное регулярное выражение этого не допускает.

Комментарии:

1. Вы знаете, как я могу также получить имя «FUY784js_7HL»

2. @Ana: Тогда вы должны принять мой ответ и проголосовать за любые ответы, которые были полезны (при условии, что у вас есть привилегия голосовать за).

Ответ №2:

Если я правильно понимаю проблему, похоже, что использование групп захвата удовлетворяет вашим потребностям. Особенно, поскольку вы знаете начало и конец, но не знаете середины, что-то вроде этого должно сработать:

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

Ознакомьтесь с разделом о группах захвата в perldoc:
http://perldoc.perl.org/perlre.html#Regular-Expressions

Комментарии:

1. Эти последовательности будут разными для каждого файла, поэтому на самом деле я не знаю ни начала, ни конца. Но если бы я мог разделить и напечатать строку для каждого термина, например, x = » , тогда я не буду утверждать, что эта последовательность букв является третьей, а имя — 6-м

Ответ №3:

Исходя из того, что было опубликовано, я думаю, что это вернет последовательность:

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