2012-11-01 19 views
5

Le stringhe in Python hanno un metodo find ("somestring") che restituisce il numero di indice per "somestring" nella stringa.Come posso trovare la prima occorrenza di una sottostringa che si verifica dopo un'altra sottostringa in python?

ma diciamo che ho una stringa simile alla seguente:

"$ 5 $ $ 7 9 Costo totale: $ 35 $ 14"

E voglio trovare l'indice della prima occorrenza di '$' che si verifica dopo la la stringa "Costo totale": vorrei essere in grado di dire a python, cercare '$', iniziando dal numero di indice per "Costo totale" e restituire il numero di indice (relativo all'intera stringa) per la prima occorrenza di "$" che trovi. Il metodo find() restituirebbe 0 e rfind() non funzionerebbe in questo caso.

Un tipo di modo kludgy per fare questo è la seguente:

def findStrAfterStr(myString, searchText, afterText): 

    splitString = myString.split(afterText) 
    myIndex = len(splitString[0]) + len(afterText) + splitString[1].find(searchText) 
    return myIndex 

myString = "$5 $7 $9  Total Cost: $35 $14" 
searchText = "$" 
afterText = "Total Cost" 

findStrAfterStr(myString, searchText, afterText) 

Ma sembra che ci dovrebbe essere un modo più semplice per fare questo, e presumo non v'è probabilmente e io proprio non lo so Cos'è. Pensieri?

Questo sarebbe particolarmente utile per affettare, quando mi ritrovo a fare questo molto:

myString[myString.find("startingSubstr"):myString.find("endingSubstr")] 

e naturalmente voglio il "endingSubstr" per essere quello che si verifica dopo il "startingSubstr".

+0

Si dovrebbe usare espressioni regolari. Inoltre, hai davvero bisogno del posizionamento di $, o hai solo bisogno di scoprire la quantità di denaro? – lolopop

+0

Sono un po 'un regex n00b - come faccio a fare questo con regex? – CQP

+0

Ancora, cosa ti serve? – lolopop

risposta

11

Utilizzare il secondo argomento opzionale di str.find:

def findStrAfterStr(myString, searchText, afterText): 
    after_index = myString.index(afterText) 
    return myString.find(searchText, after_index) 

Oppure, come suggerisce pythonm, è possibile usa regex.

Vi consiglio un approccio "faccio davvero bisogno di" per espressioni regolari, perché è spesso così difficile da capire che cosa fa il codice quando si legge di nuovo in seguito. Inoltre ho scoperto che nella maggior parte dei casi puoi fare la stessa cosa senza regexp, e ottenere il codice che è più facile da leggere nel prezzo. Confronta:

import re 

def findStrAfterStr(myString, searchText, afterText): 
    pattern = "{0}.*?({1})".format(re.escape(afterText), re.escape(searchText)) 
    match = re.search(pattern, myString) 
    return match.start(1) if match else -1 
+0

Grazie, questo è esattamente quello che volevo ... – CQP

+0

+1 per argomento 'str.find' secondo. Probabilmente vorrai lanciare in 're.escape' lì dentro per' re.search' (specialmente dato che l'esempio usa '$') –

+1

@Jon Sì, sono arrivato alla stessa conclusione. Avevo anche bisogno di usare un modificatore non avido per '. *'. –

3
def findStrAfter(myString, searchText, afterText): 
    try: 
     i = myString.index(afterText) 
     return min(i for i,char in enumerate(myString) if myString[i:].startswith(searchText) and i>afterText) 
    except ValueError: 
     print "'%s' does not exist" %afterText 

o (più efficiente):

def findStrAfter(myString, searchText, afterText): 
    try: 
     i = myString.index(afterText) 
    except ValueError: 
     print "'%s' does not exist" %afterText 
     raise 
    try: 
     return myString[i:].index(searchText) 
    except ValueError: 
     print "'%s' does not exist after '%s' in myString" %(searchText, afterText) 
     raise 

Spero che questo aiuti

1

come circa questo?

return string.index('Total Cost:') + string[string.index('Total Cost:'):].index('$') 

O

i = string.index('Total Cost:') 
return i + string[i:].index('$') 
Problemi correlati