2011-09-11 19 views
5

Sto cercando l'occorrenza di "CCGTCAATTC (A | C) TTT (A | G) AGT" in un file di testo.Espressione regolare nella funzione indice

$text = 'CCGTCAATTC(A|C)TTT(A|G)AGT'; if ($line=~/$text/){ chomp($line); $pos=index($line,$text); }

Ricerca sta lavorando, ma io non sono in grado di ottenere la posizione di "testo" in linea. Sembra che index non accetti un'espressione regolare come sottostringa.

Come posso fare questo lavoro. Grazie

risposta

13

L'array @- mantiene gli offset delle posizioni iniziali dell'ultima corrispondenza riuscita. Il primo elemento è l'offset dell'intero pattern di matching, e gli elementi successivi sono offset di sotto-pattern parentesi. Quindi, se sai che c'era una corrispondenza, puoi ottenere il suo offset come $-[0].

1

Non è necessario utilizzare lo standard index, solo un'espressione regolare. La porzione di $line che precede la corrispondenza delle espressioni regolari verrà memorizzata in $` (o $PREMATCH se si è scelto di utilizzare l'inglese;). È possibile ottenere l'indice della partita controllando la lunghezza del $`, e si può ottenere la stessa partita dal $& (o $MATCH) variabile:

$text = 'CCGTCAATTC(A|C)TTT(A|G)AGT'; 
if ($line =~ /$text/) { 
    $pos = length($PREMATCH); 
} 

Supponendo che si desidera ottenere $pos continuare corrispondenti sul restante parte di $line, è possibile utilizzare la variabile $' (o $POSTMATCH) per ottenere la parte di $line che viene dopo la corrispondenza.

Vedere http://perldoc.perl.org/perlvar.html per informazioni dettagliate su queste variabili speciali.

+0

Sì, posso farlo. Ma una volta catturata la posizione, devo catturare i seguenti 50 caratteri: 'substr ($ line, $ pos, 50)' – Deep

+0

Puoi uguagliare sulla parte restante di $ line come hai detto - questo approccio è indesiderabile per qualche ragione? Puoi anche utilizzare la variabile $ '(o $ POSTMATCH) per ottenere facilmente la parte restante di $ line. –

+0

Si prega di consultare la mia risposta modificata; fammi sapere se stai cercando qualcos'altro –

1

In base ai commenti, sembra che quello che si sta cercando corrisponda ai 50 caratteri che seguono direttamente la partita. Quindi, una soluzione semplice sarebbe:

my ($match) = $line =~ /CCGTCAATTC[AC]TTT[AG]AGT(.{50})/; 

Come si vede, [AG] è equivalente a A|G. Se si desidera abbinare più volte, è possibile utilizzare un array @matches e l'opzione globale /g sull'espressione regolare. Per esempio.

my @matches = $line =~ /CCGTCAATTC[AC]TTT[AG]AGT(.{50})/g; 

Si può fare questo per mantenere il pattern matching:

my ($pattern, $match) = $line =~ /(CCGTCAATTC[AC]TTT[AG]AGT)(.{50})/g; 

O in un ciclo:

while ($line =~ /(CCGTCAATTC[AC]TTT[AG]AGT)(.{50})/g;) { 
    my ($pattern, $match) = ($1, $2); 
} 
+0

In realtà, ho bisogno dei caratteri di abbinamento quindi potrebbe essere necessario imbrogliare e invece di 50 mettere 38 – Deep

+0

La tua domanda non sarebbe stata molto più semplice rispondi se hai detto dall'inizio cosa volevi? =) Bene, supponendo che tu sappia quanti caratteri vuoi catturare, penso che tu possa capire come risolverlo. – TLP

+0

Anche questo mi ha dato un'altra idea, così che TLP – Deep

0
while ($line =~ /(CCGTCAATTC[AC]TTT[AG]AGT)(.{50})/g;) { 

mi piace, ma non ; in while.

Ho avuto tempi difficili per cercare il motivo degli errori. T_T.