2010-09-10 31 views
7

Mir wurde ein Problem zugeordnet, um Gene zu finden, wenn eine Zeichenfolge der Buchstaben A, C, G oder T alle in einer Reihe, wie ATGCTCTCTTGATTTTTTTTATGTGTAGCCATGCACACACACACATAAGA gegeben. Ein Gen wird mit ATG gestartet und endet entweder mit TAA, TAG oder TGA (das Gen schließt beide Endpunkte aus). Das Gen besteht aus Dreiergruppen von Buchstaben, so dass seine Länge ein Vielfaches von drei ist, und keines dieser Tripel kann das Anfangs-/Ende-Triplet sein, das oben aufgelistet ist. Also, für die Zeichenfolge oberhalb der Gene sind es CTCTCT und CACACACACACA. Und tatsächlich funktioniert meine Regex für diese bestimmte Zeichenfolge. Hier ist, was ich bisher (und ich bin ziemlich glücklich mit mir, dass ich so weit gekommen):Java Regex für genom puzzle

(?<=ATG)(([ACGT]{3}(?<!ATG))+?)(?=TAG|TAA|TGA) 

Wenn es jedoch ein ATG ist und End-Triplett in einem anderen Ergebnis, und nicht mit den Triolen ausgerichtet von diesem Ergebnis versagt es. Zum Beispiel:

Results for TCGAATGTTGCTTATTGTTTTGAATGGGGTAGGATGACCTGCTAATTGGGGGGGGGG : 
TTGCTTATTGTTTTGAATGGGGTAGGA 
ACCTGC 

Es sollte auch eine GGG findet aber nicht: TTGCTTATTGTTTTGA (ATG | GGG | TAG) GA

Ich bin neu Regex im Allgemeinen und ein wenig hängen ... einfach Ein kleiner Hinweis wäre toll!

+0

Was sollte passiert mit ATGATGTAG? Match oder keine Übereinstimmung? –

+0

+1 - Ich habe keine Zeit, darüber nachzudenken, und ich weiß nicht, ob dies eine angemessene Verwendung von Regex ist, aber ich liebe die Tatsache, dass Sie es auf ein interessantes Problem in der Biologie anwenden. Gutes Zeug. – duffymo

+0

'ATGATGTAG' würde nicht übereinstimmen, da ATG nicht zu den enthaltenen Triplets gehören kann. – Swordbeard

Antwort

1

Hier ist eine mögliche regex (einige ATG kann in einem Gen zu finden):

(?=(ATG((?!ATG)[ATGC]{3})*(TAA|TAG|TGA))) 

Ein wenig Prüfstand:

public class Main { 
    public static void main(String[]args) { 
     String source = "TCGAATGTTGCTTATTGTTTTGAATGGGGTAGGATGACCTGCTAATTGGGGGGGGGGATGATGTAG"; 
     Matcher m = Pattern.compile("(?=(ATG((?!ATG)[ATGC]{3})*(TAA|TAG|TGA)))").matcher(source); 
     System.out.println("source : "+source+"\nmatches:"); 
     while(m.find()) { 
      System.out.print("   "); 
      for(int i = 0; i < m.start(); i++) { 
       System.out.print(" "); 
      } 
      System.out.println(m.group(1)); 
     } 
    } 
} 

, die produziert:

source : TCGAATGTTGCTTATTGTTTTGAATGGGGTAGGATGACCTGCTAATTGGGGGGGGGGATGATGTAG 
matches: 
      ATGTTGCTTATTGTTTTGAATGGGGTAGGATGACCTGCTAATTGGGGGGGGGGATGA 
           ATGGGGTAG 
              ATGACCTGCTAA 
                    ATGTAG 
2

Das Problem besteht darin, dass der reguläre Ausdruck die Zeichen konsumiert, die ihm entsprechen, und sie dann nicht erneut verwendet werden.

Sie können dies lösen, indem Sie entweder eine Null-Breite-Übereinstimmung verwenden (in diesem Fall erhalten Sie nur den Index der Übereinstimmung, nicht die übereinstimmenden Zeichen).

Alternativ können Sie drei ähnliche reguläre Ausdrücke verwenden, aber jeder mit einem anderen Offset:

(?=(.{3})+$)(?<=ATG)(([ACGT]{3}(?<!ATG))+?)(?=TAG|TAA|TGA) 
(?=(.{3})+.$)(?<=ATG)(([ACGT]{3}(?<!ATG))+?)(?=TAG|TAA|TGA) 
(?=(.{3})+..$)(?<=ATG)(([ACGT]{3}(?<!ATG))+?)(?=TAG|TAA|TGA) 

Sie auch einen anderen Ansatz betrachten möchten vielleicht zu verwenden, die nicht würde reguläre Ausdrücke wie die oben regulären Ausdruck beinhalten nicht langsam sein.

2

Das Problem mit solchen Dingen ist, dass Sie langsam eine Regex, Regel für Regel, aufbauen können, bis Sie etwas haben, das funktioniert.

Dann ändern sich Ihre Anforderungen und Sie müssen wieder von vorn anfangen, weil es für Normalsterbliche fast unmöglich ist, einen komplexen Regex einfach nachzubilden.

Persönlich würde ich es lieber "altmodisch" machen - benutzen Sie String-Manipulation. Jede Stufe kann leicht kommentiert werden, und wenn sich die Anforderungen leicht ändern, können Sie einfach eine bestimmte Stufe anpassen.

0

Vielleicht sollten Sie mit anderen Methoden wie Arbeiten mit Indizes versuchen. So etwas wie:

Machen Sie das gleiche für andere Codons, und sehen Sie, ob Indizes mit der Triplet-Regel übereinstimmen. Übrigens, bist du sicher, dass ein Gen ein Startcodon ausschließt?

+0

Eigentlich ist es ein Lehrbuchproblem, und es sagt mir, dass ich ATG ausschließen soll. Außerdem benötigt das Problem keine Regex und Ihre Lösung ist diejenige, die ich tun sollte, aber ich dachte, Regex wäre eine lustige Herausforderung. – Swordbeard