RegExp

  • Hey,
    ich frisch grad mein RegExp-Vertaendnis auf. Sitzt hier allerdings schon 2h an diesem Problem...
    Fuer den Koenner ist es bestimmt ein Leichtes...

    Der String: "GUUAAUGAGUAAGUAAUAAGUAG"

    Es soll immer mit "AUG" beginnen,
    dazwischen immer 3 Buchstaben, also A, U, oder G. Hier darf NICHT "UAA", "UAG", oder "UGA" hin. "AUG" schon.
    Es endet immer mit "UAA", "UAG", oder "UGA".
    Mein Ansatz: AUG([AUG]{3}*)(UAA|UAG|UGA)

    Allerdings wird AUGAGUAAGUAAUAA ausgegeben, anstatt AUGAGUAAGUAA.
    (RNA-Sequenzen)
    Ich hoffe jemand sieht das Problem.
    Bedanke mich im vorraus
    LG Diplopoda

    3 Mal editiert, zuletzt von Diplopoda (10. Dezember 2013 um 09:50)

  • Tach :D

    Ich bezweifle dass du mit diesen Pattern überhaupt eine Ausgabe erhältst. Bei deinem Ausdruck in der ersten Klammer bezieht du dich mit dem Sternchen auf den Quantifier (ich glaube der heißt so...). Und selbst wenn du das Sternchen entfernen würdest, hättest du immer noch kein Ergebnis weil es keine Zeichenfolge in deinem String gibt der mit AUG beginnt, 3 beliebige Zeichen (A, U oder G) beinhaltet und auf UAA, UAG oder UGA endet.

    Dein Ansatz war aber bisher nicht ganz verkehrt. Du benötigst nur für den ersten Ausdruck einen Quantifier welcher weitere Zeichen zulässt. Der Quantifier dafür würde in deinen Fall so aussehen: {3,}

    Dein Pattern wäre demnach folgendes: AUG[AUG]{3,}(UAA|UAG|UGA)

    Allerdings werden auch die Kombinationen aus Zeichen mitgelesen welche du nicht möchtest. Ich vermute du möchtest alle Zeichen bis zu der ersten Kombination von UAA, UAG oder UGA haben. Dies kannst du mit einem lazy (zu Deutsch: faulen) Quantifier erreichen. Dafür wird hinter dem Quantifier ein einfaches Fragezeichen gesetzt. Nun sucht dieser nur noch das nötigste um das Pattern zu erfüllen.

    Die Lösung: (AUG[AUG]{3,}?(UAA|UAG|UGA))

    Hier noch ein kleines Beispiel:

    [autoit]

    #include <Array.au3>
    $s = 'GUUAAUGAGUAAGUAAUAAGUAG'
    $p = '(AUG[AUG]{3,}?(UAA|UAG|UGA))'
    $a = StringRegExp($s, $p, 3)
    _ArrayDisplay($a)

    [/autoit]

    LG. Make :)

  • Lazy Quantifier, DAS ist das Stichwort!
    Tausend mal gelesen, aber einfach nicht in Zusammenhang gebracht!
    Vielen Dank.
    Nochmall zum Verstaendnis. Mein Quantifer {3} bedeutet doch nichts anderes als {3,3}.
    Also mindestens 3 beliebige Buchstaben aus [AUG] (z.B. AUG, GAU, UGA, GGU, etc.). Maximal aber auch nur 3.
    Das "*" bedeutet, dass diese "Dreierwiederholung" beliebig oft wiederholt wird.
    JETZT dein "?", um zu sagen, dass darin aber kein "Ende" entahlten ist, weil lazy.
    Wenn ich jetzt {3,} nehmen wuerde, muessen es mind. 3 Zeichen sein, koennen aber mehr sein.
    Also auch AUGG, oder GUGUGUA. Das darf ja nicht sein, sollen ja immer 3 sein.

    Ich hatte damit schon genau das rausbekommen, was ich da geschrieben hatte.
    Mit dem hier, bekomme ich genau das raus, was ich will:
    AUG([AUG]{3}*?)(UAA|UAG|UGA)
    Vielen Dank nochmal!!

    ps. Mit deinem geht es in diesem Fall auch! Allerdings auch, wenn ich z.B. noch Buchstaben dazutue, dann nimmt er auch 4.

    Edit: Bin mir nur nicht ganz sicher, ob es: "AUG([AUG]{3}*?)(UAA|UAG|UGA)" oder "AUG[AUG]{3}*?(UAA|UAG|UGA)" heißt.
    Beides gibt das richtige Ergebnis.

    2 Mal editiert, zuletzt von Diplopoda (10. Dezember 2013 um 10:08)

  • o.o --- Entweder arbeitet RegExp bei mir nicht richtig oder ich spinne jetzt total.
    Bei mir gibt keines deiner geposteten Pattern eine Ausgabe aus.
    Nur wenn ich deinen Ausdruck vor dem Stern in Klammern setze: (AUG(([AUG]{3})*?)(UAA|UAG|UGA))

    Bist du sicher dass es dir deine Pattern einen String zurückgeben?
    Weil es wundert mich gerade... :/

    Aber schön dass ich dir helfen konnte :)

  • Das "*" bedeutet, dass diese "Dreierwiederholung" beliebig oft wiederholt wird.


    Nope.
    Das wäre in folgendem Regex der Fall:

    Code
    ([AUG]{3})*


    Hier würden beliebig viele Blöcke (jeweils 3 Zeichen, beliebige Kombination von A's, U's und/oder G's) gefunden.
    z.B.: AUGAUG, AUGGUAAAG, UUUUUU

    Ganz nebenbei: Im Ergebnis-Array erhält man aber bei den grade gebrachten Beispielen aber nur AUG, AAG und UUU zurück - jeweils den letzten 3er-Block. Die anderen Ergebnisse werden einfach gesagt 'überschrieben'. Der oben gepostete Regex muss hier nochmal von runden Klammern umschlossen werden um das ganze Ergebnis zu erhalten! -> (([AUG]{3})*)


    Zurück zum Thema:
    Ich bin auch der Meinung, dass dein zuletzt gepostetes Pattern so nicht funktionieren sollte. Die Kombination {3}*? ist schon sehr gewöhnungsbedürftig.
    Dein Beispiel ist perfekt, um es mit einer sog. Assertion zu verwenden. Probier mal folgendes (Ungetestet, hab keinen Regexbuddy hier!)

    Code
    (AUG(?=UAA|UAG|UGA)[AUG]{3}(?:UAA|UAG|UGA))