TL;DR
- re.match()는 문자열 시작 부분만 일치시키지만 동작이 모호해 Python 3.15에서 소프트 디프리케이션되며, 새 코드는 re.prefixmatch()를 선호하는 방향임
- 소프트 디프리케이션은 기존 코드에서 API를 계속 안전하게 사용할 수 있지만 새 코드에서는 사용하지 않도록 문서로만 권고하는 방식임
- re.search()는 문자열 어디서든 일치시키고, re.fullmatch()는 문자열 전체가 일치하는지 확인하는 함수임
- re.prefixmatch()는
re.match()의 시작 부분 고정 동작을 명시적으로 표현하는 별칭이며 기존match()이름이 제거될 계획은 없음 - Ruff의
TID251규칙으로 프로젝트에서re.match()사용을 탐지하고 re.fullmatch() 또는 re.search() 사용을 권고할 수 있음
소프트 디프리케이션
- Python의 하위 호환성 정책인 PEP 387에서 2023년 소프트 디프리케이션이 도입됨.
- 소프트 디프리케이션은 새 코드를 작성할 때 더 이상 사용하지 않아야 하지만 기존 코드에서 계속 사용해도 안전한 API에 적용하는 방식임.
- 해당 API는 문서화와 테스트가 유지되지만 더 이상 개발되거나 기능이 개선되지 않음.
- 소프트 디프리케이션은 향후 API 제거를 의미하지 않으며 경고도 발생시키지 않음.
- 대체 API가 있다면 이를 제안하는 문서상의 사용 자제 권고에 해당함.
- 소프트 디프리케이션을 향후 일반적인 하드 디프리케이션으로 전환할지는 별도의 결정 사항이며, 하드 디프리케이션에서는 제거가 뒤따를 수 있음.
- 소프트 디프리케이션이 일반 디프리케이션이나 제거 단계로 자동 전환되는 것은 아님.
re.match()
re.match()는 정규 표현식이 문자열의 시작 부분에서 일치하는지 확인하는 함수임.- 정규 표현식
pi와 문자열pi를 비교하면 처음부터 끝까지pi가 일치함. pi와pie를 비교해도 문자열 시작 부분의pi가 일치함.pi와api를 비교하면 시작 부분이a이므로 일치하지 않음.pi와magpie를 비교해도 시작 부분에pi가 없어 일치하지 않음.- 따라서
re.match()는 문자열 시작 부분에만 고정되는 함수이며, 이 절반만 고정된 동작이 직관에 어긋날 수 있음.
re.search()
- 문자열 시작 부분에 고정하지 않고 문자열 어디에서든 일치시키려면
re.search()를 사용함. pi와pi및pie를 비교하면 모두 문자열 시작 위치에서 일치함.pi와api를 비교하면 위치 1~3에서 일치함.pi와magpie를 비교하면 위치 3~5에서 일치함.re.search()는 기본적으로 시작 앵커와 끝 앵커를 사용하지 않는 방식임.
re.fullmatch()
- 문자열의 시작과 끝을 모두 고정하고 전체 문자열이 일치하는지 확인하려면
re.fullmatch()를 사용함. pi와pi를 비교하면 전체 문자열이 일치함.pi와api,pie,magpie를 비교하면 앞뒤에 다른 문자가 남아 전체 일치가 아니므로 일치하지 않음.
re.prefixmatch() 도입
re.match()의 예상하기 어려운 절반 고정 동작에 대응해 Python 3.15에서re.prefixmatch()라는 새 별칭이 도입됨.- Python의 선(The Zen of Python)이 제시하는 “명시적인 것이 암시적인 것보다 낫다”는 원칙에 따라
prefixmatch()라는 이름이 의도된 동작을 더 분명하게 전달함. match()라는 이름은 이 오래된 Python 특성을 이미 아는 사람이 아니라면 의도된 동작에 의문을 남길 수 있음.
re.match()의 소프트 디프리케이션
- 더 명시적인 대체 함수가 추가되면서 Python 3.15에서
re.match()가 소프트 디프리케이션됨. - 30년 넘게 코드에서 사용된 기존
match()이름을 제거할 계획은 없음. - 이전 Python 버전을 지원하는 코드는 계속
match()를 사용해야 하며, 새 코드는prefixmatch()를 우선 사용해야 함. - 절반만 고정하는 동작이 정말 의도한 것이라면
re.prefixmatch()를 사용하고, 그렇지 않다면re.search()또는re.fullmatch()를 사용함.
비교
re.search()는 시작 앵커와 끝 앵커를 사용하지 않으며 Python 1.5부터 제공됨.- 특수 문자를 사용하면
re.search("^pi", string)또는re.search(r"\\Api", string)처럼 시작 부분을 고정할 수 있음. re.match()는 시작 앵커만 사용하고 끝 앵커는 사용하지 않으며 Python 1.5부터 제공됨.- 동등한 표현으로
re.search("^pi", string)또는re.search(r"\\Api", string)를 사용할 수 있음. re.prefixmatch()는 시작 앵커만 사용하고 끝 앵커는 사용하지 않으며 Python 3.15부터 제공됨.- 동등한 표현으로
re.search("^pi", string)또는re.search(r"\\Api", string)를 사용할 수 있음. re.fullmatch()는 시작 앵커와 끝 앵커를 모두 사용하며 Python 3.4부터 제공됨.- 동등한 표현으로
re.search("^pi$", string)또는re.search(r"\\Api\\z", string)를 사용할 수 있음. - 특수 문자를 사용하지 않는 함수 호출이 일반적으로 조금 더 빠름.
린트
- 프로젝트에서
re.match()사용을 피하려면 Ruff에서TID251규칙을 활성화할 수 있음. TID251은flake8-tidy-imports의 금지 API 규칙이며,re.match를 금지 대상으로 지정하고re.fullmatch()또는re.search()사용을 권고하는 메시지를 설정할 수 있음.- 별도 설정으로 Ruff를 실행할 때도
TID251과re.match금지 API 메시지를 지정할 수 있음. - 관련 내용으로 Seth Larson의 Python 정규 표현식 사용 권고인 “
^…$가 아니라\A…\z사용”이 있음.
출처 및 이미지
- 헤더 사진은 Hugo van Kemenade의 “Double-exposure bike and pedestrian stencils”이며 CC BY-NC-SA 2.0 라이선스임.
댓글 (0)
로그인하면 이 기사에 내 생각을 남길 수 있어요