Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I find the first occurrence of a substring occurring after another substring in python?

Strings in Python have a find("somestring") method that returns the index number for "somestring" in your string.

But let's say I have a string like the following:

"$5 $7 $9 Total Cost: $35 $14"

And I want to find the index of the first occurrence of '$' that occurs after the string "Total Cost" -- I'd like to be able to tell python, search for '$', starting at the index number for "Total Cost", and return the index number (relative to the entire string) for the first occurrence of '$' that you find. The find() method would return 0, and rfind() wouldn't work either in this case.

One kind of kludgy way to do this is the following:

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)

But it seems like there should be an easier way to do this, and I assume there probably is and I just don't know what it is. Thoughts?

This would be particular useful for slicing, when I find myself doing this a lot:

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

and naturally I want the "endingSubstr" to be the one that occurs after the "startingSubstr".

like image 816
CQP Avatar asked Nov 01 '12 19:11

CQP


Video Answer


1 Answers

Use the optional second argument of str.find:

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

Or, as pythonm suggests, you can use regexps.

I recommend a "do I really need to" approach to regexps, because it's often so hard to understand what the code does when you read it again later. Also I've found that in most cases you can do the same thing without regexp, and get code that's easier to read in the bargain. Compare:

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
like image 94
Lauritz V. Thaulow Avatar answered Sep 24 '22 17:09

Lauritz V. Thaulow