답변:
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'
'hippo'
않지만 대체 할 값이 함수에 전달되면 유용하므로 다른 것보다 좋은 예입니다.
re.escape
당신의 바늘에 기록이 대답은 피하지 여기에 또 다른 함정, 거기 stackoverflow.com/a/15831118/1709587은 :부터 re.sub
프로세스가 이스케이프 시퀀스에서 언급 한 바와 같이 docs.python.org/library/re.html#re .sub 이면 대체 문자열에서 모든 백 슬래시를 이스케이프 처리하거나 람다를 사용해야합니다.
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
만 파이썬 2.7 이후이 플래그를 지원합니다.
한 줄로 :
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
Blair Conrad와 같이 string.replace는 이것을 지원하지 않습니다.
정규식을 사용 re.sub
하지만 대체 문자열을 먼저 이스케이프해야합니다. 에 대한 플래그 옵션은 2.6에 re.sub
없으므로 임베디드 수정자를 사용해야합니다.'(?i)'
(또는 RE 객체, Blair Conrad의 답변 참조). 또한 또 다른 함정은 문자열이 제공되면 sub가 대체 텍스트에서 백 슬래시 이스케이프를 처리한다는 것입니다. 이것을 피하기 위해 대신 람다를 전달할 수 있습니다.
기능은 다음과 같습니다.
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()
기능을 모두 사용합니다 . 그것은 모든 발행 수 대체 할 pattern
의를 string
가진 repl
소문자를 구분하지 않는 방식으로.
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
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):]
구문 세부 사항 및 옵션에 대한 흥미로운 관찰 :
win32의 Python 3.7.2 (tags / v3.7.2 : 9a3ffc0492, 2018 년 12 월 23 일, 23:09:28) [MSC v.1916 64 비트 (AMD64)]
import re
old = "TREEROOT treeroot TREerOot"
re.sub(r'(?i)treeroot', 'grassroot', old)
'잔디 풀뿌리 풀뿌리'
re.sub(r'treeroot', 'grassroot', old)
'TREEROOT grassroot TREerOot'
re.sub(r'treeroot', 'grassroot', old, flags=re.I)
'잔디 풀뿌리 풀뿌리'
re.sub(r'treeroot', 'grassroot', old, re.I)
'TREEROOT grassroot TREerOot'
따라서 일치 표현식의 (? i) 접두사 또는 "flags = re.I"를 네 번째 인수로 추가하면 대소 문자를 구분하지 않습니다. 그러나 네 번째 인수로 "re.I"만 사용하면 대소 문자를 구분하지 않습니다.
비교하려고,
re.findall(r'treeroot', old, re.I)
[ 'TREEROOT', 'treeroot', 'TREerOot']
re.findall(r'treeroot', old)
[ '트리 루트']
나는 이스케이프 시퀀스 로 변환 하지 않았고 ( 비트를 아래로 스크롤) re.sub 는 백 슬래시 이스케이프 문자를 이스케이프 시퀀스로 변환 한다는 점에 주목했습니다 .
이를 방지하기 위해 다음을 작성했습니다.
대소 문자를 구분하지 않고 교체하십시오.
import re
def ireplace(findtxt, replacetxt, data):
return replacetxt.join( re.compile(findtxt, flags=re.I).split(data) )
또한 이스케이프 문자로 바꾸려면 이스케이프 시퀀스로 변환되는 특별한 의미의 bashslash 문자를 얻는 다른 답변과 같이 이스케이프 문자로 바꾸려면 찾기 및 문자열을 디코딩하십시오. 파이썬 3에서는 .decode ( "unicode_escape") # python3
findtxt = findtxt.decode('string_escape') # python2
replacetxt = replacetxt.decode('string_escape') # python2
data = ireplace(findtxt, replacetxt, data)
파이썬 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))