0

配列からすべてのメチオニン残基を最後まで抽出しようとしています。

以下の順序で:

MFEIEEHMKDSQVEYIIGLHNIPLLNATISVKCTGFQRTMNMQGCANKFMQRHYENPLTG

元のアミノ酸配列:

atgtttgaaatcgaagaacatatgaaggattcacaggtggaatacataattggccttcataatatcccattattgaatgcaactatttcagtgaagtgcacaggatttcaaagaactatgaatatgcaaggttgtgctaataaatttatgcaaagacattatgagaatcccctgacgggg

シーケンスから M 残基を最後まで抽出し、次の結果を得たいと考えています。

- MFEIEEHMKDSQVEYIIGLHNIPLLNATISVKCTGFQRTMNMQGCANKFMQRHYENPLTG
- MKDSQVEYIIGLHNIPLLNATISVKCTGFQRTMNMQGCANKFMQRHYENPLTG
- MNMQGCANKFMQRHYENPLTG
- MQGCANKFMQRHYENPLTG
- MQRHYENPLTG

私が取り組んでいるデータでは、配列にもっと多くの「M」残基がある場合があります。

私が現在持っているスクリプトは以下のとおりです。このスクリプトは、まずゲノム データを翻訳してから、アミノ酸配列を処理します。これにより、最初の 2 つの抽出が行われますが、それ以上は行われません。

2 回目のスキャン後に同じスキャン方法を繰り返そうとしましたが (以下のスクリプトのコメント部分を参照)、エラーが発生します。

private method scan called for #<Array:0x7f80884c84b0> No Method Error

ある種のループを作成する必要があることを理解しており、試してみましたが、すべて無駄でした。私もマッチングを試みましたが、できませんでした.重複する文字を単一のマッチング方法で一致させることはできないと思いますが、やはり私は初心者です...

だからここに私が使用しているスクリプトがあります:

#!/usr/bin/env ruby

require "bio" 

def extract_open_reading_frames(input)

  file_output = File.new("./output.aa", "w")
  input.each_entry do |entry|
    i = 1
    entry.naseq.translate(1).scan(/M\w*/i) do |orf1|
      file_output.puts ">#{entry.definition.to_s} 5\'3\' frame 1:#{i}\n#{orf1}"
      i = i + 1 
      orf1.scan(/.(M\w*)/i) do |orf2|
        file_output.puts ">#{entry.definition.to_s} 5\'3\' frame 1:#{i}\n#{orf2}"
        i = i + 1
        #   orf2.scan(/.(M\w*)/i) do |orf3|
        #     file_output.puts ">#{entry.definition.to_s} 5\'3\' frame 1:#{i}\n#{orf3}"
        #     i = i + 1
        #   end
      end
    end 
  end
  file_output.close
end


biofastafile = Bio::FlatFile.new(Bio::FastaFormat, ARGF)

extract_open_reading_frames(biofastafile)

これは、Ruby にある非常に長いスクリプトの一部であるため、スクリプトは Ruby にある必要があります。

4

2 に答える 2

3

できるよ:

str = "MFEIEEHMKDSQVEYIIGLHNIPLLNATISVKCTGFQRTMNMQGCANKFMQRHYENPLTG"
str.scan(/(?=(M.*))./).flatten
#=> ["MFEIEEHMKDSQVEYIIGLHNIPLLNATISVKCTGFQRTMNMQGCANKFMQRHYENPLTG", MKDSQVEYIIGLHNIPLLNATISVKCTGFQRTMNMQGCANKFMQRHYENPLTG", "MNMQGCANKFMQRHYENPLTG", "MQGCANKFMQRHYENPLTG", "MQRHYENPLTG"]

これは、M で始まり、一度に 1 文字ずつ進む先読みをキャプチャすることによって機能します。

于 2013-08-23T00:57:41.053 に答える
1
str = "MFEIEEHMKDSQVEYIIGLHNIPLLNATISVKCTGFQRTMNMQGCANKFMQRHYENPLTG"

pos = 0

while pos < str.size
  if md = str.match(/M.*/, pos)
    puts md[0]
    pos = md.offset(0)[0] + 1
  else
    break
  end
end

--output:--
MFEIEEHMKDSQVEYIIGLHNIPLLNATISVKCTGFQRTMNMQGCANKFMQRHYENPLTG
MKDSQVEYIIGLHNIPLLNATISVKCTGFQRTMNMQGCANKFMQRHYENPLTG
MNMQGCANKFMQRHYENPLTG
MQGCANKFMQRHYENPLTG
MQRHYENPLTG

md-- MatchData オブジェクトを表します。 match()-- 一致しない場合は nil を返します。2 番目の引数は検索の開始位置です。 md[0]-- は一致全体です (md[1]括弧で囲まれた最初のグループなど)。 md.offset(n)-- の文字列の開始位置と終了位置を含む配列を返しますmd[n]

文字列「MMMM」でプログラムを実行すると、次の出力が生成されます。

MMMM
MMM
MM
M

私もマッチングを試みましたが、できませんでした-重複する文字を単一のマッチング方法で一致させることはできないと思いますが、やはり私は初心者です...

はい、本当です。 String#scan重複する一致は見つかりません。一致が見つかった後scan、検索は一致の最後から続行されます。Perl には正規表現をバックアップする方法がいくつかありますが、Ruby にそれらがあるかどうかはわかりません。

編集:

Ruby 1.8.7 の場合:

str = "MFEIEEHMKDSQVEYIIGLHNIPLLNATISVKCTGFQRTMNMQGCANKFMQRHYENPLTG"

pos = 0

while true
  str = str[pos..-1]

  if md = str.match(/M.*/)
    puts md[0]
    pos = md.offset(0)[0] + 1
  else
    break
  end
end
于 2013-08-23T00:24:56.470 に答える