2017-02-17 5 views
1

Der Titel dieser Frage ist wahrscheinlich nicht ausreichend, um das Problem zu beschreiben, das ich versuche zu lösen, also hoffentlich bekommt mein Beispiel den Punkt herüber. Ich bin ein Python RegEx ist das richtige Werkzeug für den Job der Hoffnung:Python RegEx Overlapping

Zuerst sind wir für eine dieser Zeichenketten lookig:

  • CATGTG
  • CATTTG
  • CACGTG

Zweitens ist das Muster:

  • Zeichenfolge
  • 6-7 Buchstaben
  • Zeichenfolge

Beispiel

  • match: CATGTGXXXXXXCACGTG
  • no match: CATGTGXXXCACGTG (weil zwischen 3 Buchstaben)

Third, wenn eine Übereinstimmung gefunden wird, beginnen Sie die nächste Suche vom Ende des vorherigen Spiels, inklusive. Berichtsindex jedes Spiels

Beispiel:

  • Eingang (Leerzeichen zur besseren Lesbarkeit): XXX CATGTG XXXXXX CATTTG XXXXXXX CACGTG XXX

  • Workflow (Räume zur besseren Lesbarkeit):

    • gefunden Spiel: CATGTG XXXXXX CATTTG
    • beginnt es a t 3

    • Wiederaufnahme der Suche bei C in CATTTG

    • gefunden match: CATTTG XXXXXXX CACGTG

    • es beginnt bei 15

und so weiter ...

Nach ein paar Stunden Basteln, brachte mein entsetzlicher Versuch nicht, was ich erwartet hatte:

regex = re.compile("CATGTG|CATTTG|CACGTG(?=.{6,7})CATGTG|CATTTG|CACGTG") 
for m in regex.finditer('ATTCATGTG123456CATTTGCCG'): 
    print(m.start(), m.group()) 

3 CATGTG 
15 CATTTG (incorrect) 

Sie sind ein Genie, wenn Sie das mit einer RegEx herausfinden können.Danke: D

+0

Können Sie das, was Sie versucht haben, und die gewünschte Ausgabe posten? Wollen Sie ein Ja/Nein für die Test-Strings usw. – CJC

Antwort

2

Sie können diese Art von Muster verwenden:

import re 

s='XXXCATGTGXXXXXXCATTTGXXXXXXXCACGTGXXX' 

regex = re.compile(r'(?=(((?:CATGTG|CATTTG|CACGTG).{6,7}?)(?:CATGTG|CATTTG|CACGTG)))\2') 

for m in regex.finditer(s): 
    print(m.start(), m.group(1)) 

Die Idee ist, die gesamte Zeichenfolge in dem Look-Ahead zu setzen und eine Rückreferenzierung zu verwenden Zeichen verbrauchen Sie wollen nicht nach testen.

Die erste Erfassungsgruppe enthält die gesamte Sequenz, die zweite enthält alle Zeichen bis zur nächsten Startposition.

Beachten Sie, dass Sie (?:CATGTG|CATTTG|CACGTG) zu CA(?:TGTG|TTTG|CGTG) ändern können, um das Muster zu verbessern.

+2

@ WiktorStribiżew: Nein, mit 'Finderer' Ich füge es einfach hinzu. –

0

Das Hauptproblem ist, dass, um das | Zeichen zu verwenden, Sie die Alternativen in Klammern einschließen müssen.

aus Ihrem Beispiel Angenommen, dass Sie nur den ersten passenden String wollen, versuchen Sie Folgendes:

regex = re.compile("(CATGTG|CATTTG|CACGTG).{6,7}(?:CATGTG|CATTTG|CACGTG)") 
for m in regex.finditer('ATTCATGTG123456CATTTGCCG'): 
    print(m.start(), m.group(1)) 

Notierte die .group(1), die nur werden die entsprechen, was die Klammern im ersten Satz ist, im Gegensatz zu .group() Das wird das ganze Spiel zurückgeben.