# Find Index of Last Substring Occurrence in Python String

## Problem Formulation

Given a string and a substring in Python. How to find the index of the last occurrence of the substring in Python?

Let’s have a look at a couple of examples to thoroughly understand the problem:

```Example 1:
```string = 'fifi'
substring = 'fi'
result: 2```

Example 2:
```string = 'hello'
substring = 'l'
result: 3```

Example 3:
```string = 'finxter finxter finxter'
substring = 'finxter'
result: 16``````

Let’s dive into the first and most Pythonic method next!

## Method 1: rfind()

The Python `string.rfind(substr)` method returns the highest index in the string where a substring is found. Thus, it finds the index of the last occurrence of the substring in a given string or returns `-1` if not found.

Here’s an example:

```string = 'fifi'
substring = 'fi'
print(string.rfind(substring))
# 2```

For comprehensibility, let’s dive into the other two examples introduced in the problem formulation:

```string = 'hello'
substring = 'l'
print(string.rfind(substring))
# 3

string = 'finxter finxter finxter'
substring = 'finxter'
print(string.rfind(substring))
# 16
```

You can find some background information on `rfind()` and multiple other string methods in the following video—conquer string methods once and for all! 🙂

## Method 2: string.rindex()

The Python `string.rindex(substr)` method returns the highest index in the string where a substring is found. Thus, it finds the index of the last occurrence of the substring in a given string or raises a `ValueError` if not found.

Let’s have an analogous example:

```string = 'fifi'
substring = 'fi'
print(string.rindex(substring))
# 2

string = 'hello'
substring = 'l'
print(string.rindex(substring))
# 3

string = 'finxter finxter finxter'
substring = 'finxter'
print(string.rindex(substring))
# 16
```

The difference between `rfind()` and `rindex()` is that while both return the index of the last occurrence of the substring, the former returns `-1` and the latter raises a `ValueError` if the substring doesn’t exist in the string.

## Method 3: Regex Search Negative Lookahead

Just for fun, here’s a regular expression that finds the index of the last occurrence of a substring in a given string:

``re.search(substring + '(?!.*' + substring + ')', string).start()``

Before I’ll explain it to you, let’s have a look at whether it really does what it is supposed to do! 🙂

```import re

string = 'fifi'
substring = 'fi'
print(re.search(substring + '(?!.*' + substring + ')', string).start())
# 2

string = 'hello'
substring = 'l'
print(re.search(substring + '(?!.*' + substring + ')', string).start())
# 3

string = 'finxter finxter finxter'
substring = 'finxter'
print(re.search(substring + '(?!.*' + substring + ')', string).start())
# 16
```

Okay, it works—but why?

You need to understand a couple of regular expression concepts for this:

• The `re.search(pattern, string)` method finds the first occurrence of the `pattern` in the given `string`.
• We use the pattern `substring + '(?!.*' + substring + ')'` that finds the first occurrence of the substring for which no other occurrence of `substring` follows in the string. This is the last occurrence of `substring` in the string.
• The expression `(?! ... )` is called negative lookahead and it makes sure that the pattern within it does not follow immediately afterwards (no/negative match).
• The return value of `re.search()` is a match object on which we can call the `.start()` method to obtain the index of the match in the original `string`.