대소 문자를 구분하지 않음


답변:


217

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'

11
단일 바꾸기 만 수행하거나 코드 줄을 저장하려는 경우 re.sub 및 (? i) 플래그로 단일 대체를 사용하는 것이 더 효율적입니다. re.sub ( '(? i)'+ re .escape ( 'hippo'), 'giraffe', '생일을위한 hIPpo를 원합니다')
D Coetzee

3
왜 문자열 만 다시 이스케이프 합니까? 감사.
Elena

8
@Elena는 필요하지 'hippo'않지만 대체 할 값이 함수에 전달되면 유용하므로 다른 것보다 좋은 예입니다.
블레어 콘래드

2
에 가진 게다가 re.escape당신의 바늘에 기록이 대답은 피하지 여기에 또 다른 함정, 거기 stackoverflow.com/a/15831118/1709587은 :부터 re.sub프로세스가 이스케이프 시퀀스에서 언급 한 바와 같이 docs.python.org/library/re.html#re .sub 이면 대체 문자열에서 모든 백 슬래시를 이스케이프 처리하거나 람다를 사용해야합니다.
Mark Amery

84
import re
pattern = re.compile("hello", re.IGNORECASE)
pattern.sub("bye", "hello HeLLo HELLO")
# 'bye bye bye'

17
또는 한 줄짜리 : re.sub('hello', 'bye', 'hello HeLLo HELLO', flags=re.IGNORECASE)
Louis Yang

참고 re.sub만 파이썬 2.7 이후이 플래그를 지원합니다.
fuenfundachtzig

47

한 줄로 :

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'

14

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

잘 했어요 정규식보다 훨씬 낫습니다. 그것은 모든 종류의 문자를 처리하는 반면 정규 표현식은 영숫자가 아닌 것에 대해 매우 까다 롭습니다. 우선 답변 IMHO.
fyngyrz

당신이해야 할 일은 정규 표현식을 피하는 것입니다. 허용 된 답변은 이것보다 훨씬 짧고 읽기 쉽습니다.
Mad Physicist

탈출은 일치하는 경우에만 작동하며 대상의 백 슬래시는 여전히 문제를 일으킬 수 있습니다.
ideasman42

4

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'

4

이 기능은 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

3

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):] 

3
그러나 좋은 것은 새로운 것으로 모든 오래된 항목을 변경하지는 않지만 첫 번째 항목 만 변경합니다.
rsmoorthy

5
정규식보다 읽기가 어렵습니다. 여기서 바퀴를 다시 만들 필요가 없습니다.
Johannes Bittner

이 버전과 업그레이드 된 버전간에 성능을 비교하는 것이 흥미로울 수 있습니다. 일부 애플리케이션에서는 더 빠를 수 있습니다. 또는 해석 된 파이썬에서 더 많은 작업을 수행하기 때문에 속도가 느려질 수 있습니다.
D Coetzee

2

구문 세부 사항 및 옵션에 대한 흥미로운 관찰 :

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)

[ '트리 루트']


이것은 질문에 대한 답변을 제공하지 않습니다. 제발 편집 은이 질문에 이미 존재하는 다른 답변에 개선하도록 답변을.
hongsy

1

나는 이스케이프 시퀀스 로 변환 하지 않았고 ( 비트를 아래로 스크롤) 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에서 테스트

희망이 도움이됩니다.


0

전에 답변을 게시하지 않았고이 스레드는 실제로 오래되었지만 다른 해결책을 생각해 내고 응답을 얻을 수 있다고 생각했습니다 .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))

2
학습 : 일반적으로 문자열을 검색하고 바꿀 때 먼저 배열로 바꿀 필요가 없습니다. 그렇기 때문에 첫 번째 대답이 가장 좋은 이유입니다. 외부 모듈을 사용하는 동안 문자열을 하나의 전체 문자열로 취급합니다. 또한 프로세스에서 일어나는 일이 조금 더 명확합니다.
isaaclw

학습 : 문맥이없는 개발자 가이 코드를 읽고 수행하는 작업을 해독하는 것은 매우 어렵습니다 :)
Todd
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.