2016-01-13 23 views
6

Ho qualche problema con il metodo re.finditer() in python. Per esempio:re.finditer() che restituisce lo stesso valore per i metodi di inizio e fine

>>>sequence = 'atgaggagccccaagcttactcgatttaacgcccgcagcctcgccaaaccaccaaacacacca' 
>>>[[m.start(),m.end()] for m in re.finditer(r'(?=gatttaacg)',sequence)] 

out: [[22,22]] 

Come si può vedere, le start() e end() metodi stanno dando lo stesso valore. L'ho notato prima e ho appena finito di usare m.start()+len(query_sequence), invece di m.end(), ma sono molto confuso perché questo sta accadendo.

+2

Perché stai utilizzando un lookahead? –

+0

Sto usando il lookahead perché voglio corrispondenze sovrapposte. Ad esempio, se stavo cercando aca, vorrei che l'acaca contasse 2 occorrenze invece di 1 – lstbl

+1

Beh, sai la lunghezza della sequenza richiesta, quindi perché hai bisogno di 'm.end()'? – kay

risposta

4

Il modulo regex supporta sovrapposizione con finditer:

import regex 
sequence = 'acaca' 
print [[m.start(), m.end()] for m in regex.finditer(r'(aca)', sequence, overlapped=1)] 
[0, 3], [2, 5]] 
+1

Bella risposta. Questo ha senso. – lstbl

+3

@lstbl: Si noti che il modulo 'regex' in questa risposta è un modulo completamente diverso dal modulo' re' della libreria standard che si sta utilizzando. – user2357112

+2

Non ho notato che – lstbl

2
sequence = 'atgaggagccccaagcttactcgatttaacgcccgcagcctcgccaaaccaccaaacacacca' 
print [[m.start(),m.end()] for m in re.finditer(r'(gatttaacg)',sequence)] 

rimuovere il lookahead. Non acquisisce solo asserzioni.

uscita: [[22, 31]]

se si deve usare lookahead uso

sequence = 'atgaggagccccaagcttactcgatttaacgcccgcagcctcgccaaaccaccaaacacacca' 
print [[m.start(),m.start()+len("aca")] for m in re.finditer(r'(?=aca)',sequence)] 
+3

Un chiarimento: ciò significa che quando 're.finditer' corrisponde a' gatttaacg', i valori effettivi non vengono consumati. Va solo in quella posizione e dice "sì, quello che precede questa posizione è la stringa richiesta". – Kupiakos

+0

quindi la funzione end() è praticamente inutile se si sta utilizzando un lookahead? – lstbl

+1

@lstbl 'lookaheads' non consumare alcuna stringa.Essi controllano una stringa dopo una posizione. Si ottiene l'avvio ma il motore regex rimane lì poiché non viene consumata alcuna stringa in seguito – vks

1

Come specificato, si sono tenuti a trovare le corrispondenze che si sovrappongono e hanno bisogno del lookahead. Tuttavia, sembra che tu conosca la stringa esatta che stai cercando. Cosa ne pensi di questo?

def find_overlapping(sequence, matchstr): 
    for m in re.finditer('(?={})'.format(matchstr)): 
     yield (m.start(), m.start() + len(matchstr)) 

In alternativa, è possibile utilizzare il modulo di terze parti di Python regex, come descritto here.

+0

Questo funziona. Era quello che stavo usando originariamente. Sono ancora un po 'confuso perché il motore regex non è in grado di determinare la durata della corrispondenza (ad esempio se la lunghezza della corrispondenza delle espressioni regolari non è nota apriori, come nel mio caso), poiché è ancora in grado di determinare se c'è una corrispondenza. – lstbl

+1

@lstbl, può. 'm.start()' e 'm.end()' si riferiscono agli span del gruppo 0, che è vuoto. Quindi stai solo interpretando male l'API. – kay

1

Se la lunghezza della sottosequenza non è nota a priori, quindi è possibile utilizzare un gruppo corrispondente all'interno del lookahead e prendere il suo span:

[m.span(1) for m in re.finditer(r'(?=(gatttaacg))',sequence)] == [(22,31)] 

Es. per trovare tutti i caratteri ripetuti:

[m.span(1) for m in re.finditer(r'(?=(([acgt])\2+))',sequence)] 
Problemi correlati