Me gustaría usar la función .replace para reemplazar varias cadenas.
Actualmente tengo
string.replace("condition1", "")
pero me gustaría tener algo como
string.replace("condition1", "").replace("condition2", "text")
aunque eso no parece buena sintaxis
¿Cuál es la forma apropiada de hacer esto? algo así como cómo en grep / regex puedes hacer \1
y \2
reemplazar campos a ciertas cadenas de búsqueda
Respuestas:
Aquí hay un breve ejemplo que debería hacer el truco con expresiones regulares:
Por ejemplo:
fuente
"spamham sha".replace("spam", "eggs").replace("sha","md5")
ser en"eggmd5m md5"
lugar de"eggsham md5"
Podrías hacer una pequeña y agradable función de bucle.
donde
text
está la cadena completa ydic
es un diccionario: cada definición es una cadena que reemplazará una coincidencia con el término.Nota : en Python 3,
iteritems()
se ha reemplazado conitems()
Cuidado: los diccionarios Python no tienen un orden confiable para la iteración. Esta solución solo resuelve su problema si:
Por ejemplo:
Salida posible # 1:
Salida posible # 2
Una posible solución es usar un OrderedDict.
Salida:
Cuidado # 2: ineficiente si su
text
cadena es demasiado grande o si hay muchos pares en el diccionario.fuente
OrderedDict
o una lista de 2 tuplas.¿Por qué no una solución como esta?
fuente
Aquí hay una variante de la primera solución que usa reducir, en caso de que le guste ser funcional. :)
La versión aún mejor de martineau:
fuente
repls
una secuencia de tuplas y eliminar laiteritems()
llamada. es decirrepls = ('hello', 'goodbye'), ('world', 'earth')
yreduce(lambda a, kv: a.replace(*kv), repls, s)
. También funcionaría sin cambios en Python 3.reduce
se ha eliminado .reduce
todavía existe, sin embargo, se hizo parte delfunctools
módulo (ver los documentos ) en Python 3, así que cuando dije sin cambios, quise decir que se podía ejecutar el mismo código, aunque es cierto que requeriría quereduce
se hayaimport
editado si es necesario ya que ya no es incorporado.Esta es solo una recapitulación más concisa de las excelentes respuestas de FJ y MiniQuark. Todo lo que necesita para lograr múltiples reemplazos de cadena simultáneos es la siguiente función:
Uso:
Si lo desea, puede realizar sus propias funciones de reemplazo dedicadas a partir de esta más simple.
fuente
rep_dict = {"but": "mut", "mutton": "lamb"}
la cadena"button"
da como resultado"mutton"
su código, pero daría"lamb"
si los reemplazos estuvieran encadenados, uno tras otro.Do you prefer cafe? No, I prefer cafe.
, lo cual no es deseable en absoluto.Construí esto sobre la excelente respuesta de FJ:
Uso de un disparo:
Tenga en cuenta que dado que el reemplazo se realiza en una sola pasada, "café" cambia a "té", pero no vuelve a "café".
Si necesita hacer el mismo reemplazo muchas veces, puede crear una función de reemplazo fácilmente:
Mejoras:
¡Disfrutar! :-)
fuente
pattern.sub
espera una función con solo un parámetro (el texto a reemplazar), por lo que la función debe tener accesoreplace_dict
.re.M
permite reemplazos de líneas múltiples (se explica bien en el documento: docs.python.org/2/library/re.html#re.M ).Me gustaría proponer el uso de plantillas de cadena. ¡Simplemente coloque la cadena que se reemplazará en un diccionario y todo está listo! Ejemplo de docs.python.org
fuente
substitute
genera una excepción, así que tenga cuidado al obtener plantillas de los usuarios.En mi caso, necesitaba un reemplazo simple de claves únicas con nombres, así que pensé esto:
fuente
i
cons
, obtendría un comportamiento extraño.b = [ ['i', 'Z'], ['s', 'Y'] ]; for x,y in (b): a = a.replace(x, y)
luego, si tiene cuidado de ordenar sus pares de matriz, puede asegurarse de no reemplazar () de forma recursiva.Comenzando
Python 3.8
, y la introducción de expresiones de asignación (PEP 572) (:=
operador), podemos aplicar los reemplazos dentro de una comprensión de lista:fuente
['The quick red fox jumps over the lazy dog', 'The quick red fox jumps over the quick dog']
. Pero la expresión de asignación (text := text.replace
) también construye iterativamente nuevas versiones detext
mutando. Después de la comprensión de la lista, puede usar latext
variable que contiene el texto modificado.text
one-liner, también puede usar[text := text.replace(a, b) for a, b in replacements][-1]
(observe la[-1]
), que extrae el último elemento de la comprensión de la lista; es decir, la última versión detext
.Aquí mis $ 0.02. Se basa en la respuesta de Andrew Clark, un poco más clara, y también cubre el caso cuando una cadena para reemplazar es una subcadena de otra cadena para reemplazar (la cadena más larga gana)
Es en esto en lo esencial , siéntase libre de modificarlo si tiene alguna propuesta.
fuente
Necesitaba una solución donde las cadenas a ser reemplazadas pueden ser expresiones regulares, por ejemplo, para ayudar a normalizar un texto largo reemplazando múltiples caracteres de espacios en blanco por uno solo. Partiendo de una cadena de respuestas de otros, incluidos MiniQuark y mmj, esto es lo que se me ocurrió:
Funciona para los ejemplos dados en otras respuestas, por ejemplo:
Lo principal para mí es que también puedes usar expresiones regulares, por ejemplo para reemplazar solo palabras enteras o para normalizar espacios en blanco:
Si desea utilizar las teclas del diccionario como cadenas normales, puede escapar de ellas antes de llamar a multiple_replace utilizando, por ejemplo, esta función:
La siguiente función puede ayudar a encontrar expresiones regulares erróneas entre las teclas del diccionario (ya que el mensaje de error de multiple_replace no es muy revelador):
Tenga en cuenta que no encadena los reemplazos, sino que los realiza simultáneamente. Esto lo hace más eficiente sin limitar lo que puede hacer. Para imitar el efecto del encadenamiento, es posible que solo necesite agregar más pares de reemplazo de cadenas y garantizar el orden esperado de los pares:
fuente
Aquí hay una muestra que es más eficiente en cadenas largas con muchos reemplazos pequeños.
El punto es evitar muchas concatenaciones de cadenas largas. Cortamos la cadena de origen en fragmentos, reemplazando algunos de los fragmentos a medida que formamos la lista, y luego unimos todo de nuevo en una cadena.
fuente
Realmente no deberías hacerlo de esta manera, pero me parece demasiado genial:
Ahora,
answer
es el resultado de todos los reemplazos a su vez.De nuevo, esto es muy hacky y no es algo que debas usar regularmente. Pero es bueno saber que puedes hacer algo como esto si alguna vez lo necesitas.
fuente
Estaba luchando con este problema también. Con muchas sustituciones, las expresiones regulares luchan y son aproximadamente cuatro veces más lentas que los bucles
string.replace
(en las condiciones de mi experimento).Debería intentar usar la biblioteca Flashtext ( publicación de blog aquí , Github aquí ). En mi caso , fue un poco más de dos órdenes de magnitud más rápido, de 1.8 sa 0.015 s (las expresiones regulares tomaron 7.7 s) para cada documento.
Es fácil encontrar ejemplos de uso en los enlaces anteriores, pero este es un ejemplo de trabajo:
Nota que Flashtext hace sustituciones en una sola pasada (para evitar a -> b y b -> c traducción 'a' en 'c'). Flashtext también busca palabras completas (por lo que 'es' no coincidirá con ' es '). Funciona bien si su objetivo son varias palabras (reemplazando 'Esto es' por 'Hola').
fuente
<p>
con/n
. ¿Intenté tu enfoque pero con las etiquetas flashtext no parece analizarlo?<
y>
marcar el final de una palabra (pero ser incluido en el reemplazo)?Siento que esta pregunta necesita una respuesta de función lambda recursiva de una sola línea para completar, solo porque. Por lo tanto, allí:
Uso:
Notas:
Nota: Al igual que con todas las funciones recursivas en Python, una profundidad de recursión demasiado grande (es decir, diccionarios de reemplazo demasiado grandes) dará como resultado un error. Ver, por ejemplo, aquí .
fuente
sys.getrecursionlimit()
es una pareja 1000, máx. use un bucle o algo así, o intente simplificar las sustituciones.No sé acerca de la velocidad, pero esta es mi solución rápida para el día de trabajo:
... pero me gusta la respuesta # 1 de expresiones regulares anterior. Nota: si un nuevo valor es una subcadena de otro, entonces la operación no es conmutativa.
fuente
Puede usar la
pandas
biblioteca y lareplace
función que admite coincidencias exactas y reemplazos de expresiones regulares. Por ejemplo:Y el texto modificado es:
Puedes encontrar un ejemplo aquí . Observe que los reemplazos en el texto se realizan con el orden en que aparecen en las listas
fuente
Para reemplazar solo un personaje, use
translate
ystr.maketrans
es mi método favorito.tl; dr>
result_string = your_string.translate(str.maketrans(dict_mapping))
manifestación
fuente
A partir de la preciosa respuesta de Andrew, desarrollé un script que carga el diccionario de un archivo y elabora todos los archivos en la carpeta abierta para hacer los reemplazos. El script carga las asignaciones de un archivo externo en el que puede establecer el separador. Soy un principiante, pero este script me pareció muy útil al hacer múltiples sustituciones en múltiples archivos. Cargó un diccionario con más de 1000 entradas en segundos. No es elegante pero funcionó para mí.
fuente
Esta es mi solución al problema. Lo usé en un chatbot para reemplazar las diferentes palabras a la vez.
esto se convertirá
The cat hunts the dog
fuente
Otro ejemplo: lista de entrada
La salida deseada sería
Código:
fuente
O simplemente para un truco rápido:
fuente
Aquí hay otra forma de hacerlo con un diccionario:
fuente