Was ist der einfachste Weg, um in Python die Zeichenfolge ohne Berücksichtigung der Groß- und Kleinschreibung zu ersetzen?
Was ist der einfachste Weg, um in Python die Zeichenfolge ohne Berücksichtigung der Groß- und Kleinschreibung zu ersetzen?
Antworten:
Der string
Typ unterstützt dies nicht. Verwenden Sie am besten die Submethode für reguläre Ausdrücke mit der Option re.IGNORECASE .
>>> import re
>>> insensitive_hippo = re.compile(re.escape('hippo'), re.IGNORECASE)
>>> insensitive_hippo.sub('giraffe', 'I want a hIPpo for my birthday')
'I want a giraffe for my birthday'
'hippo'
, wäre aber nützlich, wenn der zu ersetzende Wert an eine Funktion übergeben würde, also ist es wirklich mehr ein gutes Beispiel als alles andere.
re.escape
Ihre Nadel benötigen , gibt es hier eine weitere Falle, die mit dieser Antwort nicht vermieden werden kann. Diese wird in stackoverflow.com/a/15831118/1709587 vermerkt : Da re.sub
Prozesse Sequenzen entgehen, wie in docs.python.org/library/re.html#re angegeben .sub , müssen Sie entweder alle Schrägstriche in Ihrem Ersatz - String zu entkommen oder ein Lambda verwenden.
import re
pattern = re.compile("hello", re.IGNORECASE)
pattern.sub("bye", "hello HeLLo HELLO")
# 'bye bye bye'
re.sub('hello', 'bye', 'hello HeLLo HELLO', flags=re.IGNORECASE)
re.sub
dieses Flag nur seit Python 2.7 unterstützt wird.
In einer einzigen Zeile:
import re
re.sub("(?i)hello","bye", "hello HeLLo HELLO") #'bye bye bye'
re.sub("(?i)he\.llo","bye", "he.llo He.LLo HE.LLO") #'bye bye bye'
Oder verwenden Sie das optionale Argument "flags":
import re
re.sub("hello", "bye", "hello HeLLo HELLO", flags=re.I) #'bye bye bye'
re.sub("he\.llo", "bye", "he.llo He.LLo HE.LLO", flags=re.I) #'bye bye bye'
Wenn Sie die Antwort von bFloch fortsetzen, ändert diese Funktion nicht nur eine, sondern alle Vorkommen von Altem mit Neuem - in einer Weise, in der die Groß- und Kleinschreibung nicht berücksichtigt wird.
def ireplace(old, new, text):
idx = 0
while idx < len(text):
index_l = text.lower().find(old.lower(), idx)
if index_l == -1:
return text
text = text[:index_l] + new + text[index_l + len(old):]
idx = index_l + len(new)
return text
Wie Blair Conrad sagt, unterstützt string.replace dies nicht.
Verwenden Sie den regulären Ausdruck re.sub
, aber denken Sie daran, zuerst die Ersatzzeichenfolge zu maskieren. Beachten Sie, dass es in 2.6 für keine Flags-Option gibt re.sub
, daher müssen Sie den eingebetteten Modifikator verwenden '(?i)'
(oder ein RE-Objekt, siehe Blair Conrads Antwort). Eine weitere Gefahr besteht darin, dass Sub Backslash-Escapezeichen im Ersatztext verarbeitet, wenn eine Zeichenfolge angegeben wird. Um dies zu vermeiden, kann man stattdessen ein Lambda abgeben.
Hier ist eine Funktion:
import re
def ireplace(old, repl, text):
return re.sub('(?i)'+re.escape(old), lambda m: repl, text)
>>> ireplace('hippo?', 'giraffe!?', 'You want a hiPPO?')
'You want a giraffe!?'
>>> ireplace(r'[binfolder]', r'C:\Temp\bin', r'[BinFolder]\test.exe')
'C:\\Temp\\bin\\test.exe'
Diese Funktion verwendet sowohl die str.replace()
als auch die re.findall()
Funktionen. Es wird alle Vorkommen von pattern
in string
mit repl
einer Groß- und Kleinschreibung nicht berücksichtigen.
def replace_all(pattern, repl, string) -> str:
occurences = re.findall(pattern, string, re.IGNORECASE)
for occurence in occurences:
string = string.replace(occurence, repl)
return string
Dies erfordert kein RegularExp
def ireplace(old, new, text):
"""
Replace case insensitive
Raises ValueError if string not found
"""
index_l = text.lower().index(old.lower())
return text[:index_l] + new + text[index_l + len(old):]
Eine interessante Beobachtung zu Syntaxdetails und -optionen:
Python 3.7.2 (tags / v3.7.2: 9a3ffc0492, 23. Dezember 2018, 23:09:28) [MSC v.1916 64-Bit (AMD64)] unter win32
import re
old = "TREEROOT treeroot TREerOot"
re.sub(r'(?i)treeroot', 'grassroot', old)
"Graswurzel Graswurzel Graswurzel"
re.sub(r'treeroot', 'grassroot', old)
'TREEROOT Graswurzel TREerOot'
re.sub(r'treeroot', 'grassroot', old, flags=re.I)
"Graswurzel Graswurzel Graswurzel"
re.sub(r'treeroot', 'grassroot', old, re.I)
'TREEROOT Graswurzel TREerOot'
Das Präfix (? I) im Übereinstimmungsausdruck oder das Hinzufügen von "flags = re.I" als viertes Argument führt also zu einer Übereinstimmung ohne Berücksichtigung der Groß- und Kleinschreibung. ABER die Verwendung von "re.I" als viertes Argument führt nicht zu einer Übereinstimmung ohne Berücksichtigung der Groß- und Kleinschreibung.
Zum Vergleich,
re.findall(r'treeroot', old, re.I)
['TREEROOT', 'Treeroot', 'TREerOot']
re.findall(r'treeroot', old)
['Baumwurzel']
Ich hatte keine Konvertierung in die Escape-Sequenzen (scrollen Sie etwas nach unten), daher habe ich festgestellt, dass re.sub umgekehrte Escape-Zeichen in Escape-Sequenzen konvertiert.
Um dies zu verhindern, habe ich folgendes geschrieben:
Ersetzen Sie die Groß- und Kleinschreibung nicht.
import re
def ireplace(findtxt, replacetxt, data):
return replacetxt.join( re.compile(findtxt, flags=re.I).split(data) )
Wenn Sie möchten, dass es durch die Escape-Zeichen ersetzt wird, wie die anderen Antworten hier, bei denen die Bashslash-Zeichen mit besonderer Bedeutung in Escape-Sequenzen konvertiert werden, dekodieren Sie einfach Ihre Such- und / oder Ersetzungszeichenfolge. In Python 3 muss möglicherweise etwas wie .decode ("unicode_escape") # python3 ausgeführt werden
findtxt = findtxt.decode('string_escape') # python2
replacetxt = replacetxt.decode('string_escape') # python2
data = ireplace(findtxt, replacetxt, data)
Getestet in Python 2.7.8
Hoffentlich hilft das.
Ich habe noch nie eine Antwort gepostet und dieser Thread ist wirklich alt, aber ich habe mir eine andere Lösung ausgedacht und dachte, ich könnte Ihre Antwort bekommen. Ich bin nicht in der Python-Programmierung erfahren. Wenn es also offensichtliche Nachteile gibt, weisen Sie sie bitte darauf hin, da es gut gelernt hat: )
i='I want a hIPpo for my birthday'
key='hippo'
swp='giraffe'
o=(i.lower().split(key))
c=0
p=0
for w in o:
o[c]=i[p:p+len(w)]
p=p+len(key+w)
c+=1
print(swp.join(o))