[EXT-003][입문] 문자열 모양을 정규식으로 확인하기 > IT 기술 공유

본문 바로가기
사이트 내 전체검색

IT 기술 공유

[EXT-003][입문] 문자열 모양을 정규식으로 확인하기

페이지 정보

profile_image
작성자 기술팀장
댓글 0건 조회 15회 작성일 26-09-07 16:33

본문

[이번 수업]
정규 표현식은 문자열 모양을 설명하는 규칙입니다. 주문 코드를 로컬 Python에서 검사하며 패턴 읽기와 전체 일치를 익힙니다. 짧고 제한된 패턴을 정확하게 쓰는 데 집중합니다.

[선수지식]
PY-002의 문자열과 PY-003의 리스트, BACK-005의 입력 검증 개념을 알면 좋습니다. Python 파일을 만들고 실행할 수 있으면 충분합니다.

[학습목표]
1. 리터럴, 문자 집합, 반복 횟수를 읽습니다.
2. `fullmatch()`로 입력 전체가 규칙에 맞는지 확인합니다.
3. 정규식으로 확인할 형식과 별도 코드로 확인할 의미를 구분합니다.

[핵심개념]
정규 표현식, 줄여서 정규식은 글자의 반복과 위치를 기호로 나타내는 패턴입니다. `[A-Z]`는 영문 대문자 한 글자, `[0-9]`는 ASCII 숫자 한 글자, `{3}`은 바로 앞 규칙을 정확히 세 번 반복한다는 뜻입니다. 따라서 `[A-Z]{3}-[0-9]{4}`는 대문자 세 글자, 하이픈, 숫자 네 자리로 된 코드 모양을 나타냅니다.

`search()`는 문자열 안의 일부를 찾지만 `fullmatch()`는 처음부터 끝까지 모두 맞아야 성공합니다. 입력 한 칸 전체는 보통 `fullmatch()`, 긴 로그에서 조각을 찾을 때는 `search()`가 알맞습니다.

Python에서는 정규식 앞에 `r`을 붙인 원시 문자열을 자주 씁니다. `r"\d+"`처럼 쓰면 Python 문자열의 역슬래시 처리와 정규식의 역슬래시 처리를 덜 헷갈릴 수 있습니다. 다만 Python의 `\d`는 기본적으로 유니코드의 십진 숫자도 포함합니다. 영문 코드의 숫자를 0부터 9로 제한하려면 `[0-9]`처럼 의도를 분명히 적습니다.

정규식은 형식을 확인할 뿐 의미까지 보장하지 않습니다. `[0-9]{4}`는 `0000`도 통과시키므로 실제 연도 범위가 필요하면 숫자로 바꾼 뒤 별도 조건문으로 검사해야 합니다. 이메일, URL, 프로그래밍 언어처럼 규칙이 큰 대상을 한 줄 정규식으로 모두 해석하려 하지 말고 전용 파서나 표준 라이브러리를 우선 검토하세요.

[따라하기]
빈 폴더에 pattern_check.py를 만들고 다음 코드를 저장합니다.

```python
import re

code_pattern = re.compile(r"[A-Z]{3}-[0-9]{4}")
samples = ["ABC-2026", "AB-2026", "ABC-20A6", "ABC-0000"]

for value in samples:
    shape_ok = code_pattern.fullmatch(value) is not None
    year_ok = shape_ok and 2000 <= int(value[-4:]) <= 2099
    result = "통과" if year_ok else "거부"
    print(f"{value}: {result}")
```

macOS와 Linux에서는 `python3 pattern_check.py`, Windows에서는 `py pattern_check.py`로 실행합니다. 예상 결과는 다음과 같습니다.

```text
ABC-2026: 통과
AB-2026: 거부
ABC-20A6: 거부
ABC-0000: 거부
```

첫 번째 검사는 문자열 모양을 확인하고, 두 번째 검사는 연도가 2000~2099 범위인지 확인합니다. 형식과 의미를 나누면 패턴이 짧아지고 오류 메시지도 더 구체적으로 만들 수 있습니다. 운영체제에 따른 코드 차이는 없습니다.

[흔한 실수]
`search()` 결과만으로 입력 전체가 유효하다고 판단하지 마세요. 점 `.`은 아무 글자 한 개이므로 실제 점은 `\.`로 씁니다. 일반 문자열을 패턴에 붙일 때는 `re.escape()`를 쓰고, 거대한 패턴은 작은 검사나 전용 파서로 나누세요.

[보안 주의]
일부 정규식 엔진은 모호한 반복을 되돌아가며 확인해 입력이 길 때 CPU를 오래 쓸 수 있습니다. 이를 정규식 서비스 거부, ReDoS라고 합니다. 외부 입력은 먼저 최대 길이를 제한하고, 중첩된 무제한 반복을 피하며, 긴 실패 입력으로 성능 테스트를 합니다. 필요하면 시간 제한이나 선형 시간 엔진을 선택하세요. 실습은 본인 소유의 로컬·격리 환경과 짧은 가짜 문자열에서만 진행합니다.

[직접 해볼 과제]
코드 규칙을 `대문자 두 글자-숫자 여섯 자리`로 바꾸고 정상 2개, 형식 오류 2개, 범위 오류 1개를 테스트하세요. 입력 길이가 20자를 넘으면 정규식을 실행하기 전에 거부하고, 형식 오류와 연도 오류를 다른 메시지로 출력해 보세요.

[확인문제]
1. `search()`와 `fullmatch()`의 차이는 무엇인가요?
2. 영문 코드에서 `\d`보다 `[0-9]`가 의도를 더 분명히 하는 이유는 무엇인가요?
3. 형식 검사와 의미 검사를 나누면 어떤 장점이 있나요?

[다음 학습]
다음 확장 수업에서는 `없음`, 빈 문자열, 숫자 0을 구분합니다. 데이터베이스의 NULL과 프로그램의 빈 값을 섞을 때 생기는 오류를 작은 예제로 확인합니다.

[공식 참고 자료]
Python re 공식 문서
https://docs.python.org/3/library/re.html

Python 정규 표현식 HOWTO
https://docs.python.org/3/howto/regex.html

Unicode Technical Standard #18
https://www.unicode.org/reports/tr18/

POSIX 정규 표현식 표준
https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/V1_chap09.html

OWASP ReDoS 설명
https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS

CWE-1333 비효율적인 정규식 복잡도
https://cwe.mitre.org/data/definitions/1333.html

댓글목록

등록된 댓글이 없습니다.

회원로그인

회원가입

사이트 정보

회사명 : 회사명 / 대표 : 대표자명
주소 : OO도 OO시 OO구 OO동 123-45
사업자 등록번호 : 123-45-67890
전화 : 02-123-4567 팩스 : 02-123-4568
통신판매업신고번호 : 제 OO구 - 123호
개인정보관리책임자 : 정보책임자명

접속자집계

오늘
4,800
어제
6,862
최대
16,772
전체
770,751
Copyright © 소유하신 도메인. All rights reserved.