簡體   English   中英

不區分大小寫的替換

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM