programing

대소문자를 구분하지 않는 교환

goodsources 2022. 11. 29. 21:49
반응형

대소문자를 구분하지 않는 교환

Python에서 대소문자를 구분하지 않고 문자열을 교체하는 가장 쉬운 방법은 무엇입니까?

stringtype은 이 기능을 지원하지 않습니다.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

여기에는 Regular Exp가 필요하지 않습니다.

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

Blair Conrad의 말처럼 string.replace는 이것을 지원하지 않는다.

정규식을 사용하다re.sub단, 먼저 치환 문자열을 이스케이프해야 합니다.2.6에는 flags-option은 없습니다.re.sub따라서 내장 수식자를 사용해야 합니다.'(?i)'(또는 RE 오브젝트, Blair Conrad의 답변 참조).또 다른 함정은 문자열이 지정되면 서브가 대체 텍스트에서 백슬래시 이스케이프를 처리하는 것입니다.이것을 피하기 위해 람다를 대신 통과시킬 수 있다.

다음 기능이 있습니다.

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()기능들.그것은 모든 발생을 대체할 것이다.patternstring와 함께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

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

Python 3.7.2 (태그/v3.7.2:9a3ffc0492, 2018년 12월 23일 23:09:28) [MSC v.1916 64비트(AMD64)] (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'

즉, match 식에 접두사(?i)가 추가되거나 "filen=re"가 추가됩니다.I"는 네 번째 인수로 대소문자를 구분하지 않는 일치가 된다.근데 're'만 쓰면 돼요.I"는 네 번째 인수로 대소문자를 구분하지 않습니다.

비교를 위해서

re.findall(r'treeroot', old, re.I)

['트레루트', '트레루트', '트레어우트']

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 문자를 이스케이프 시퀀스로 변환하는 다른 답변과 마찬가지로 이스케이프 문자로 대체하려면 검색 및/또는 문자열을 디코딩하십시오.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에서 테스트 완료

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

언급URL : https://stackoverflow.com/questions/919056/case-insensitive-replace

반응형