Cách dễ nhất để thực hiện thay thế chuỗi không phân biệt chữ hoa chữ thường trong Python là gì?
Cách dễ nhất để thực hiện thay thế chuỗi không phân biệt chữ hoa chữ thường trong Python là gì?
Câu trả lời:
Các string
loại không hỗ trợ này. Có lẽ bạn tốt nhất nên sử dụng phương thức phụ biểu thức chính quy với tùy chọn 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'
, nhưng sẽ hữu ích nếu giá trị thay thế được truyền vào một hàm, vì vậy nó thực sự là một ví dụ tốt hơn bất kỳ thứ gì khác.
re.escape
dùng kim của bạn, còn có một cái bẫy khác mà câu trả lời này không thể tránh được, được ghi chú trong stackoverflow.com/a/15831118/1709587 : kể từ khi re.sub
xử lý các chuỗi thoát, như đã lưu ý trong docs.python.org/l Library / re.html # re .sub , bạn cần thoát khỏi tất cả các dấu gạch chéo ngược trong chuỗi thay thế của bạn hoặc sử dụng lambda.
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
chỉ hỗ trợ cờ này kể từ Python 2.7.
Trong một dòng duy nhất:
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'
Hoặc, sử dụng đối số "cờ" tùy chọn:
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'
Tiếp tục câu trả lời của bFloch, chức năng này sẽ thay đổi không chỉ một mà là tất cả các lần xuất hiện cũ với mới - trong trường hợp không nhạy cảm.
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
Giống như Blair Conrad nói string.replace không hỗ trợ điều này.
Sử dụng regex re.sub
, nhưng nhớ thoát chuỗi thay thế trước. Lưu ý rằng không có tùy chọn cờ trong 2.6 cho re.sub
, vì vậy bạn sẽ phải sử dụng công cụ sửa đổi được nhúng'(?i)'
(hoặc đối tượng RE, xem câu trả lời của Blair Conrad). Ngoài ra, một cạm bẫy khác là phụ sẽ xử lý dấu gạch chéo ngược trong văn bản thay thế, nếu một chuỗi được đưa ra. Để tránh điều này thay vào đó có thể vượt qua trong lambda.
Đây là một chức năng:
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'
Hàm này sử dụng cả hàm str.replace()
và re.findall()
hàm. Nó sẽ thay thế tất cả các lần xuất hiện của pattern
ở string
với repl
một cách case-insensitive.
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
Điều này không yêu cầu thường xuyênExp
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):]
Một quan sát thú vị về chi tiết cú pháp và các tùy chọn:
Python 3.7.2 (tags / v3.7.2: 9a3ffc0492, ngày 23 tháng 12 năm 2018, 23:09:28) [MSC v.1916 64 bit (AMD64)] trên win32
import re
old = "TREEROOT treeroot TREerOot"
re.sub(r'(?i)treeroot', 'grassroot', old)
'cơ sở cơ sở'
re.sub(r'treeroot', 'grassroot', old)
'TREEROOT cơ sở TREerOot'
re.sub(r'treeroot', 'grassroot', old, flags=re.I)
'cơ sở cơ sở'
re.sub(r'treeroot', 'grassroot', old, re.I)
'TREEROOT cơ sở TREerOot'
Vì vậy, tiền tố (? I) trong biểu thức khớp hoặc thêm "flags = re.I" làm đối số thứ tư sẽ dẫn đến kết quả khớp không phân biệt chữ hoa chữ thường. NHƯNG, chỉ sử dụng "re.I" làm đối số thứ tư không dẫn đến kết quả khớp không phân biệt chữ hoa chữ thường.
Để so sánh,
re.findall(r'treeroot', old, re.I)
['TREEROOT', 'treeroot', 'TREerOot']
re.findall(r'treeroot', old)
['gốc cây']
Tôi đã được chuyển đổi thành các chuỗi thoát (cuộn xuống một chút), vì vậy tôi lưu ý rằng re.sub chuyển đổi các ký tự thoát bị gạch chéo ngược thành các chuỗi thoát.
Để ngăn chặn điều đó tôi đã viết như sau:
Thay thế trường hợp không nhạy cảm.
import re
def ireplace(findtxt, replacetxt, data):
return replacetxt.join( re.compile(findtxt, flags=re.I).split(data) )
Ngoài ra, nếu bạn muốn nó thay thế bằng các ký tự thoát, giống như các câu trả lời khác ở đây đang nhận được các ký tự bashslash có ý nghĩa đặc biệt được chuyển đổi thành chuỗi thoát, chỉ cần giải mã chuỗi tìm và thay thế chuỗi của bạn. Trong Python 3, có thể phải làm một cái gì đó như .decode ("unicode_escape") # python3
findtxt = findtxt.decode('string_escape') # python2
replacetxt = replacetxt.decode('string_escape') # python2
data = ireplace(findtxt, replacetxt, data)
Đã thử nghiệm trong Python 2.7.8
Mong rằng sẽ giúp.
chưa bao giờ đăng câu trả lời trước đây và chủ đề này thực sự cũ nhưng tôi đã đưa ra một câu hỏi khác và nhận ra tôi có thể nhận được phản hồi của bạn, tôi không dày dạn trong lập trình Python vì vậy nếu có những hạn chế đáng chú ý đối với nó, xin vui lòng chỉ ra vì nó học tốt: )
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))