Я должен заменить строку в случае, если чувствительный путь. Например,
abc -> def Abc -> Def aBc -> dEf abC -> deF
Что я могу сделать это с Python?
from string import maketrans
"Abc".translate(maketrans("abcABC", "defDEF"))
Я понимаю, что Вы хотите изменить регистр второй строки в соответствии с первой. Я прав? Итак, мое решение заключается в следующем. Строка s2 изменяет свой регистр в соответствии с регистром соответствующей строки s1. Результат сохраняется в s3. Одно из предположений здесь - обе строки имеют одинаковую длину.
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
Вот метод, использующий регулярные выражения. Ключевым моментом является то, что когда он находит совпадение, он сначала модифицирует заменяющую строку, чтобы она соответствовала регистру совпавшей строки. Это работает, потому что re.sub
может принимать функцию в качестве замены, а не просто строку.
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)
Результат:
def -> def Def -> Def dEf -> dEf deF -> deF
Не самый эффективный способ и очень грубый, но, вероятно, может сработать что-то вроде этого:
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)
Модуль re
- это, вероятно, то, что вы ищете. В частности, функция re.sub
может быть использована для простого поиска/замены строк.
Это будет работать, хотя вы, вероятно, захотите добавить несколько проверок того, что длины строк одинаковы:
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))))
Долгое время таился, подумал, что выложу здесь предложение, так как некоторые из них кажутся довольно запутанными.
print map(lambda a, b: b.lower() if a.islower() else b.upper(), "aBc", "def")
Предполагается, что обе строки имеют одинаковую длину, однако вы можете легко заменить лямбда на подходящую функцию и проверить None на первом входе.