[英]Case insensitive replace
在 Python 中進行不區分大小寫的字符串替換的最簡單方法是什么?
string
類型不支持這一點。 您可能最好使用帶有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'
import re
pattern = re.compile("hello", re.IGNORECASE)
pattern.sub("bye", "hello HeLLo HELLO")
# 'bye bye bye'
在一行中:
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'
或者,使用可選的“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'
繼續 bFloch 的回答,這個函數不會改變一個,而是所有舊的和新的 - 以不區分大小寫的方式。
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
就像布萊爾康拉德說的 string.replace 不支持這個。
使用正則表達式re.sub
,但請記住首先對替換字符串進行轉義。 請注意,2.6 中沒有用於re.sub
標志選項,因此您必須使用嵌入的修飾符'(?i)'
(或 RE 對象,請參閱 Blair Conrad 的回答)。 此外,另一個陷阱是 sub 將處理替換文本中的反斜杠轉義,如果給定字符串。 為了避免這種情況,可以改為傳入 lambda。
這是一個函數:
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'
該函數使用兩個str.replace()
和re.findall()
函數。 它將以不區分大小寫的方式用repl
替換string
所有出現的pattern
。
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
關於語法細節和選項的有趣觀察:
Python 3.7.2 (tags/v3.7.2:9a3ffc0492, Dec 23 2018, 23:09:28) [MSC v.1916 64 位 (AMD64)] on win32
import re
old = "TREEROOT treeroot TREerOot"
re.sub(r'(?i)treeroot', 'grassroot', old)
'草根草根草根'
re.sub(r'treeroot', 'grassroot', old)
'TREEROOT 草根 TREerOot'
re.sub(r'treeroot', 'grassroot', old, flags=re.I)
'草根草根草根'
re.sub(r'treeroot', 'grassroot', old, re.I)
'TREEROOT 草根 TREerOot'
因此匹配表達式中的 (?i) 前綴或添加“flags=re.I”作為第四個參數將導致不區分大小寫的匹配。 但是,僅使用“re.I”作為第四個參數不會導致不區分大小寫的匹配。
為了比較,
re.findall(r'treeroot', old, re.I)
['樹根','樹根','樹根']
re.findall(r'treeroot', old)
['樹根']
這不需要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):]
我正在將 \\t 轉換為轉義序列(向下滾動一點),所以我注意到re.sub將反斜杠轉義字符轉換為轉義序列。
為了防止這種情況,我寫了以下內容:
替換不區分大小寫。
import re
def ireplace(findtxt, replacetxt, data):
return replacetxt.join( re.compile(findtxt, flags=re.I).split(data) )
此外,如果您希望它用轉義字符替換,就像這里的其他答案將特殊含義的 bashslash 字符轉換為轉義序列一樣,只需解碼您的查找和或替換字符串。 在 Python 3 中,可能需要做一些類似 .decode("unicode_escape") # python3 的事情
findtxt = findtxt.decode('string_escape') # python2
replacetxt = replacetxt.decode('string_escape') # python2
data = ireplace(findtxt, replacetxt, data)
在 Python 2.7.8 中測試
希望有幫助。
以前從未發布過答案,這個帖子真的很舊,但我想出了另一個解決方案,並認為我可以得到您的回復,我沒有在 Python 編程方面經驗豐富,所以如果它有明顯的缺點,請指出它們,因為它很好學習: )
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))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.