Encontrar la última aparición de subcadena en cadena, reemplazando eso
104
Así que tengo una lista larga de cadenas en el mismo formato y quiero encontrar el último "." carácter en cada uno y reemplazarlo con ". -". Intenté usar rfind, pero parece que no puedo utilizarlo correctamente para hacer esto.
Muchas gracias tio. Tendré que estudiar eso por un minuto ... esto es utilizar rodajas, ¿verdad?
Adam Magyar
@AdamMagyar sí, el contenedor [a: b] corta desde un índice hasta b-1 del contenedor. Si se omite 'a', el valor predeterminado es 0; si se omite 'b', el valor predeterminado es len (contenedor). El operador más simplemente concatena. La función rfind, como señaló, devuelve el índice alrededor del cual debe realizarse la operación de reemplazo.
Definitivamente me gusta esta solución, pero tener un replacements=Noneparámetro me parece un error porque si se omite el parámetro, la función dará un error (probado en Python 2.7). Sugeriría eliminar el valor predeterminado, establecerlo en -1 (para reemplazos ilimitados) o mejor hacerlo replacements=1(que creo que debería ser el comportamiento predeterminado para esta función en particular de acuerdo con lo que quiere el OP). De acuerdo con la documentación, este parámetro es opcional, pero debe ser un int si se proporciona.
remarkov
En caso de que alguien quiere una sola línea para esto: ". -".join("asd.asd.asd.".rsplit(".", 1)). Todo lo que está haciendo es realizar una división de cadena desde el lado derecho para una aparición y volver a unir la cadena utilizando el reemplazo.
bsplosion
14
Usaría una expresión regular:
import re
new_list =[re.sub(r"\.(?=[^.]*$)", r". - ", s)for s in old_list]
Esto está mal . Estás invirtiendo la cuerda, reemplazándola y luego invirtiéndola. Lo estás haciendo .replacecon una cuerda invertida. Ambas cuerdas pasaron para replacetener que invertirse también. De lo contrario, cuando invierta la cadena por segunda vez, las letras que acaba de insertar estarán al revés. Solo puede usar esto si está reemplazando una letra con una letra, e incluso entonces no pondría esto en su código en caso de que alguien tenga que cambiarlo en el futuro y comience a preguntarse por qué se escribe una palabra sdrawkcab.
Boris
1
Puede usar la función a continuación que reemplaza la primera aparición de la palabra de la derecha.
def replace_from_right(text: str, original_text: str, new_text: str)-> str:""" Replace first occurrence of original_text by new_text. """return text[::-1].replace(original_text[::-1], new_text[::-1],1)[::-1]
a ="A long string with a . in the middle ending with ."
fchar ='.'
rchar ='. -'
a[::-1].replace(fchar, rchar[::-1],1)[::-1]Out[2]:'A long string with a . in the middle ending with . -'
Esto también invierte la cuerda de reemplazo. Aparte de eso, es una repetición de la respuesta de root y, como digo allí, bastante ineficiente.
Gareth Latty
@Lattyware ¿Quieres decir que se invierte a?
Alex L
Quiero decir que se invierte '. -'en la salida.
Gareth Latty
Esperar que el usuario invierta el literal de cadena a mano no es una gran idea; es propenso a errores y poco claro.
Gareth Latty
@Lattyware de acuerdo. Lo hice var. (Me doy cuenta de que es un método ineficaz y no es adecuado en todos los casos; el suyo replace_rightes mucho mejor)
Respuestas:
Esto debería hacerlo
fuente
Para reemplazar desde la derecha:
En uso:
fuente
replacements=None
parámetro me parece un error porque si se omite el parámetro, la función dará un error (probado en Python 2.7). Sugeriría eliminar el valor predeterminado, establecerlo en -1 (para reemplazos ilimitados) o mejor hacerloreplacements=1
(que creo que debería ser el comportamiento predeterminado para esta función en particular de acuerdo con lo que quiere el OP). De acuerdo con la documentación, este parámetro es opcional, pero debe ser un int si se proporciona.". -".join("asd.asd.asd.".rsplit(".", 1))
. Todo lo que está haciendo es realizar una división de cadena desde el lado derecho para una aparición y volver a unir la cadena utilizando el reemplazo.Usaría una expresión regular:
fuente
\.(?=[^.]*$)
Un trazador de líneas sería:
str=str[::-1].replace(".",".-",1)[::-1]
fuente
.replace
con una cuerda invertida. Ambas cuerdas pasaron parareplace
tener que invertirse también. De lo contrario, cuando invierta la cadena por segunda vez, las letras que acaba de insertar estarán al revés. Solo puede usar esto si está reemplazando una letra con una letra, e incluso entonces no pondría esto en su código en caso de que alguien tenga que cambiarlo en el futuro y comience a preguntarse por qué se escribe una palabra sdrawkcab.Puede usar la función a continuación que reemplaza la primera aparición de la palabra de la derecha.
fuente
# si desea encontrar el índice de la última aparición de cualquier cadena, en nuestro caso # encontraremos el índice de la última aparición de con
# el resultado será 44, ya que el índice comienza desde 0.
fuente
Enfoque ingenuo:
La respuesta de Aditya Sihag con un solo
rfind
:fuente
a
?'. -'
en la salida.replace_right
es mucho mejor)