Necesito reemplazar una cadena en mayúsculas y minúsculas. Por ejemplosustitución de cadena sensible a mayúsculas y minúsculas en Python
abc -> def Abc -> Def aBc -> dEf abC -> deF
¿Qué puedo hacer con Python?
Necesito reemplazar una cadena en mayúsculas y minúsculas. Por ejemplosustitución de cadena sensible a mayúsculas y minúsculas en Python
abc -> def Abc -> Def aBc -> dEf abC -> deF
¿Qué puedo hacer con Python?
from string import maketrans
"Abc".translate(maketrans("abcABC", "defDEF"))
Esto supone que el mismo carácter no aparece dos veces en la cadena de entrada. –
Esto no funcionará para reemplazar "foo" por "bar" ya que el carácter "o" debe asignarse a "a" o "r" según el contexto. –
El módulo re
es probablemente lo que estás buscando. Específicamente, la función re.sub
se puede usar para búsqueda/reemplazo de cadenas simples.
're.sub' no mantendrá las mayúsculas originales de la cadena. Si entiendo correctamente, el póster original quiere conservar las mayúsculas. –
@Tam Ah, después de leer la pregunta nuevamente, creo que entendí mal lo que estaba pidiendo.Si está buscando efectivamente un reemplazo de cadena insensible a mayúsculas y minúsculas seguido de un "hacer coincidir el caso con la versión anterior", entonces sí, 're.sub' no será la solución correcta ... a menos que se pase una función personalizada como el argumento de reemplazo. Incluso entonces, probablemente no. – Rakis
la manera más eficiente, y es muy crudo, pero probablemente algo como esto podría funcionar:
def case_insensitive_replace(string, old, new):
upper_indices = [idx for idx, char in enumerate(string) if char.isupper()]
replaced = list(string.lower().replace(old.lower(), new.lower()))
for idx in upper_indices:
replaced[idx] = replaced[idx].upper()
return "".join(replaced)
Aquí es un método que utiliza expresiones regulares. El punto clave es que cuando encuentra una coincidencia, primero modifica la cadena de reemplazo para que coincida con la carcasa de la cadena coincidente. Esto funciona porque re.sub
puede tomar una función como reemplazo en lugar de solo una cadena.
import re
def case_sensitive_replace(s, before, after):
regex = re.compile(re.escape(before), re.I)
return regex.sub(lambda x: ''.join(d.upper() if c.isupper() else d.lower()
for c,d in zip(x.group(), after)), s)
test = '''
abc -> def
Abc -> Def
aBc -> dEf
abC -> deF
'''
result = case_sensitive_replace(a, 'abc', 'def')
print(result)
Resultado:
def -> def Def -> Def dEf -> dEf deF -> deF
entiendo que usted quiere cambiar el segundo caso cadena de acuerdo con la primera cadena. ¿Tengo razón? Entonces, mi solución es la siguiente. La cadena s2 cambia su caso de acuerdo con la cadena correspondiente s1. El resultado es almacenar en s3. Una suposición aquí es que las dos cadenas tienen la misma longitud.
s1 = "AaBb"
s2 = "cdef"
s3 = ""
index = 0
length = len(s1)
while(True):
if s1[index].isupper():
temp = s2[index].upper()
else:
temp = s2[index].lower()
s3 = s3 + temp
index +=1
if index == length:
break
print s3
Long time lurker, pensé en publicar una sugerencia aquí ya que algunos de estos parecen bastante intrincados.
print map(lambda a, b: b.lower() if a.islower() else b.upper(), "aBc", "def")
lo hace asumen ambas cadenas son de la misma longitud, sin embargo, puede fácilmente reemplazar el lambda con una función adecuada y comprobar si hay ninguno en la primera entrada.
Esto funcionará, aunque es probable que desee añadir algunos cheques que las longitudes de cadena son los mismos:
string1 = "AbcDEFghiJKLmnO"
string2 = "some other text"
string2 = "".join((string2[i].upper() if string1[i].isupper() else string2[i].lower()
for i in range(len(string1))))
Ampliando la respuesta de Mark Byers, he aquí una solución que funciona para el texto de reemplazo de cualquier longitud.
El truco es enviar una función al re.sub().
import re
def case_sensitive_replace(string, old, new):
""" replace occurrences of old with new, within string
replacements will match the case of the text it replaces
"""
def repl(match):
current = match.group()
result = ''
all_upper=True
for i,c in enumerate(current):
if i >= len(new):
break
if c.isupper():
result += new[i].upper()
else:
result += new[i].lower()
all_upper=False
#append any remaining characters from new
if all_upper:
result += new[i+1:].upper()
else:
result += new[i+1:].lower()
return result
regex = re.compile(re.escape(old), re.I)
return regex.sub(repl, string)
print case_sensitive_replace("abc Abc aBc abC ABC",'abc','de')
print case_sensitive_replace("abc Abc aBc abC ABC",'abc','def')
print case_sensitive_replace("abc Abc aBc abC ABC",'abc','defg')
Resultado:
de De dE de DE
def Def dEf deF DEF
defg Defg dEfg deFg DEFG
@ Marcos: wiki utiliza caracteres en mayúsculas/minúsculas para el nombre wiki. Necesito reemplazar algunos nombres de wiki. – prosseek
¿Cuál sería el reemplazo de 'wSg'? – joaquin
Es posible que la respuesta a la pregunta que ha hecho no lo ayude con el problema que está tratando de resolver. ¿Qué pasa si el antes y el después tienen diferentes longitudes? –