Potrzebuję zamienić ciąg znaków w sposób uwzględniający wielkość liter. Na przykład:Rozróżnianie wielkości liter w pytaniu w Pythonie
abc -> def Abc -> Def aBc -> dEf abC -> deF
Co mogę zrobić z Pythonem?
Potrzebuję zamienić ciąg znaków w sposób uwzględniający wielkość liter. Na przykład:Rozróżnianie wielkości liter w pytaniu w Pythonie
abc -> def Abc -> Def aBc -> dEf abC -> deF
Co mogę zrobić z Pythonem?
from string import maketrans
"Abc".translate(maketrans("abcABC", "defDEF"))
Zakłada się, że ten sam znak nie pojawia się dwukrotnie w ciągu wejściowym. –
To nie zadziała dla zamiany "foo" na "bar", ponieważ znak "o" musi być odwzorowany na "a" lub "r" w zależności od kontekstu. –
Moduł re
jest prawdopodobnie tym, czego szukasz. W szczególności funkcja re.sub
może być wykorzystana do prostego wyszukiwania/zamiany ciągów znaków.
're.sub' nie zachowuje oryginalnej wielkości liter w łańcuchu. Jeśli dobrze rozumiem, oryginalny plakat chce zachować wielkość liter. –
@Tam Ah, po ponownym przeczytaniu pytania, chyba źle zrozumiałem, o co prosił.Jeśli szuka efektywnego, niewrażliwego na wielkość znaków zastępującego łańcuch, po którym następuje "make case pasuje do poprzedniej wersji", to tak, 're.sub' nie będzie właściwym rozwiązaniem ... chyba że funkcja niestandardowa zostanie przekazana jako argument zastępczy. Nawet wtedy, prawdopodobnie nie. – Rakis
Nie jest to najbardziej efektywny sposób, i to jest bardzo surowy, ale chyba coś takiego może działać:
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)
Oto metoda za pomocą wyrażeń regularnych. Kluczową kwestią jest to, że po znalezieniu dopasowania najpierw modyfikuje zastępczy ciąg, dopasowany do obudowy dopasowanego ciągu. Działa to, ponieważ re.sub
może przyjąć funkcję zastępczą zamiast tylko ciąg.
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)
Wynik:
def -> def Def -> Def dEf -> dEf deF -> deF
Rozumiem, że chcesz zmienić drugi przypadek ciąg według pierwszego łańcucha. Mam rację? Moje rozwiązanie jest następujące. Łańcuch s2 zmienia wielkość liter zgodnie z odpowiadającym ciągiem s1. Wynik jest zapisywany w s3. Jednym z założeń jest to, że dwa łańcuchy mają tę samą długość.
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
Długo czaić się, myślałem, że zamieszczę tutaj sugestię, ponieważ niektóre z nich wydają się dość zawiłe.
print map(lambda a, b: b.lower() if a.islower() else b.upper(), "aBc", "def")
Czyni zakładać oba łańcuchy są tej samej długości, jednak można łatwo zastąpić lambda z właściwą funkcję i sprawdzić Żaden pierwszego wejścia.
To będzie działać, chociaż prawdopodobnie chcesz dodać kilka czeków, że długości strun są takie same:
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))))
Rozwijając na odpowiedź Mark Byers', Oto rozwiązanie, które działa dla tekstu zastępczego o dowolnej długości.
Sztuką jest wysłanie funkcji do 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')
Wynik:
de De dE de DE
def Def dEf deF DEF
defg Defg dEfg deFg DEFG
@Mark: wiki wykorzystuje górna/dolna znaków dla nazwy wiki. Muszę zastąpić niektóre nazwy wiki. – prosseek
Jaki byłby zamiennik "WSg"? – joaquin
Jest możliwe, że odpowiedź na zadane pytanie nie pomoże w rozwiązaniu problemu, który próbujesz rozwiązać. Co jeśli przed i po mają różne długości? –