Buscar índice de la última aparición de una subcadena en una cadena


Quiero encontrar la posición (o índice) de la última aparición de una cierta subcadena en dado ingresado cadena str.

Por ejemplo, supongamos que el ingresado cadena str = 'hello' y la subcadena es target = 'l', entonces debe de salida 3.

¿Cómo puedo hacer esto?

 208
Author: nbro, 2012-03-05

7 answers

Uso .rfind():

>>> s = 'hello'
>>> s.rfind('l')
3

Tampoco use str como nombre de variable o sombreará el built-in str().

 370
Author: Rik Poggi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-03-05 19:15:12

Puede utilizar rfind() o rindex()
Python2 enlaces: rfind() rindex()

>>> s = 'Hello StackOverflow Hi everybody'

>>> print( s.rfind('H') )
20

>>> print( s.rindex('H') )
20

>>> print( s.rfind('other') )
-1

>>> print( s.rindex('other') )
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: substring not found

La diferencia es cuando la subcadena no se encuentra, rfind() devuelve -1 mientras que rindex() plantea una excepción ValueError (Enlace Python2: ValueError).

Si no desea verificar el código de retorno rfind() -1, puede preferir rindex() que proporcionará un mensaje de error comprensible. De lo contrario, puede buscar minutos donde el el valor inesperado -1 proviene de su código...


Ejemplo: Búsqueda del último carácter de nueva línea

>>> txt = '''first line
... second line
... third line'''

>>> txt.rfind('\n')
22

>>> txt.rindex('\n')
22
 55
Author: olibre,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-23 09:43:53

Utilice el método str.rindex.

>>> 'hello'.rindex('l')
3
>>> 'hello'.index('l')
2
 34
Author: rmmh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-03-05 19:15:18

Prueba esto:

s = 'hello plombier pantin'
print (s.find('p'))
6
print (s.index('p'))
6
print (s.rindex('p'))
15
print (s.rfind('p'))
 3
Author: Gad,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-10-21 13:36:55

El more_itertools la biblioteca ofrece herramientas para encontrar índices de todos los caracteres o todas las subcadenas .

Dado

import more_itertools as mit


s = "hello"
pred = lambda x: x == "l"

Código

Caracteres

Ahora está el rlocate herramienta disponible:

next(mit.rlocate(s, pred))
# 3

Una herramienta complementaria es locate:

list(mit.locate(s, pred))[-1]
# 3

mit.last(mit.locate(s, pred))
# 3

Subcadenas

También hay un parámetro window_size disponible para localizar el elemento principal de varios temas:

s = "How much wood would a woodchuck chuck if a woodchuck could chuck wood?"
substring = "chuck"
pred = lambda *args: args == tuple(substring)

next(mit.rlocate(s, pred=pred, window_size=len(substring)))
# 59
 2
Author: pylang,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-01 03:14:17

Si no quieres usar rfind entonces esto hará el truco /

def find_last(s, t):
    last_pos = -1
    while True:
        pos = s.find(t, last_pos + 1)
        if pos == -1:
            return last_pos
        else:
            last_pos = pos
 1
Author: Salam,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-23 17:15:54

No intento resucitar un post inactivo, pero ya que esto no ha sido publicado todavía...

(Así es como lo hice antes de encontrar esta pregunta)

s = "hello"
target = "l"
last_pos = len(s) - 1 - s[::-1].index(target)

Explicación: Cuando estás buscando la última ocurrencia, realmente estás buscando la primera ocurrencia en la cadena invertida. Sabiendo esto, hice s[::-1] (que devuelve una cadena invertida), y luego indexé el target desde allí. Entonces hice len(s) - 1 - the index found porque queremos el índice en el unversed (i. e. original) cadena.

¡Cuidado, sin embargo! Si target es más de un carácter, probablemente no lo encontrará en la cadena invertida. Para arreglar esto, use last_pos = len(s) - 1 - s[::-1].index(target[::-1]), que busca una versión invertida de target.

 1
Author: Adi219,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-07 14:17:59