본문 바로가기
python

python - 정규 표현식 사용법과 예제( validate IP, email, phone )

by 맑은안개 2019. 12. 24.

파이썬은 정규 표현식을 위해 내장 라이브러리 re.py를 제공합니다. 

간단한 예제와 함께 re.py 가 제공하는 함수를 살펴보겠습니다.

 

본 장에서는 정규 표현에 사용되는 메타문자(meta characters)의 기본 사용법은

다루지 않습니다.

구동환경은 Anaconda에 내장된 Spyder 툴을 사용했습니다. - python3.7 

 

참조 : https://docs.python.org/3/library/re.html


re.compile(pattern, flags=0)

 - 정규 표현식 패턴을 컴파일 합니다. 컴파일된 정규 표현식 객체는 match(), search() 및 기타 함수에 사용됩니다.

prog = re.compile(pattern)
result = prog.match(string)

위 구문은 아래와 같습니다.

result = re.match(pattern, string)

 

a 와 e 사이의 3개의 문자를 가지는 단어 매치

In [1]: prog = re.compile(r'a...e')
In [2]: prog.match('apple')
Out[2]: <re.Match object; span=(0, 5), match='apple'> 

In [3]: re.match(r'a...e', 'apple')
Out[3]: <re.Match object; span=(0, 5), match='apple'>

compile과 match 함수에 flags 파라미터로 정규표현식 처리에 다양한 옵션을 제공합니다.

 

re.IGNORECASE - 대소문자 구분 무시

In [1]: re.match(r'a...e', 'APple', re.IGNORECASE)
Out[1]: <re.Match object; span=(0, 5), match='APple'>

 

re.VERBOSE

 - 패턴에 개행 및 주석처리하여 가독성 증가

 - 정규식 패턴이 장황해진다면 VERBOSE 옵션을 사용하여 패턴의 가독성을 높이고 중요 패턴에 주석을 남기길 추천합니다.

 - 핸드폰번호 매치

In [1]: re.match(r"""(010|011) # 핸드폰번호는 010, 011 앞자리를 갖는다.
-{0,1} # 하이픈 0개 또는 1개 
\d{4}  # 중간번호는 네자리
-{0,1} # 하이픈 0개 또는 1개
\d{4}  # 마지막 번호는 네자리
""", '01023233434', re.VERBOSE)
Out[1]: <re.Match object; span=(0, 11), match='01023233434'>

 

re.search(pattern, string, flags=0)

 - match와 다르게 문자열 전체를 통과하여 패턴 매칭합니다. 

 - 매치된 첫번째 대상을 리턴합니다.

In [1]: re.search('c', 'abcdabcd')
Out[1]: <re.Match object; span=(2, 3), match='c'>

In [2]: re.match('c', 'abcdabcd') # None - 매치는 주어진 문자열을 통과하지 않습니다.

 

re.findall(pattern, string, flags=0)

 - 패턴과 매치되는 대상 모두 찾고 리스트로 반환합니다.

 - 패턴에 한개이상의 그룹( ) 을 사용한 경우 매핑된 그룹을 리스트로 리턴합니다.

re.findall('\d{3}', '1234 567 89 012 34 567')
Out[1]: ['123', '567', '012', '567']

 - 아파치 서버로그 기록내용 중 INFO 레벨에서 실행된 함수 찾기

origin = """
2020-01-30 10:19:29,085[INFO ][kr.co.python.dao.SELECTMAP::getData]biz start..
2020-01-30 10:19:29,085[DEBUG][kr.co.python.dao.SELECTMAP::getData] DATA=[A=1,B=2]
2020-01-30 10:19:29,085[INFO ][kr.co.python.dao.SELECTMAP::setData]biz start..
"""

re.findall(r'\[\s*INFO\s*\]\[.*::(\w+).*\]', origin)
Out[1]: ['getData', 'setData']

 

정규식 예제

※ 아래 예제는 상세한 정규처리가 되지않은 예제이니 참고용도로만 사용하시기 바랍니다.

이메일 검증

p = 'http[s]?://(?:[0-9a-zA-Z]|[$-_@.&+])+'
re.search(p, 'https://docs.python.org/3/library/')
Out[1]: <re.Match object; span=(0, 34), match='https://docs.python.org/3/library/'>

IP 검증

p = '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$'
re.search(p, '244.242.255.244')
Out[1]: <re.Match object; span=(0, 15), match='244.242.255.244'>

re.search(p, '10.20.200.300') # None - 범위 초과

대한민국 지역전화번호 검증( re.X 는 VERBOSE 의 Simple 표현식 )

p = """
0(2|31|32|33|41|42|43|44|51|52|53|54|55|61|62|63|64) # 지역번호 구분 앞자리
\-{0,1}
\d{3,4} # 중간번호 3 or 4 자리
\-{0,1}
\d{4}   # 마지막번호 4 자리
"""

re.search(p, "055-123-1234", re.X)
Out[1]: <re.Match object; span=(0, 12), match='055-123-1234'>

Out[2]: re.search(p, "099-123-1234", re.X) # None - 앞자리 지역번호 미존재 케이스

주민등록번호 검증( 19세기 출생자 제외 & 마지막 유효값 확인 불가(=계산식으로 처리 해야 함) ) 

jumin_p = """
^                                # search 매칭시 ^ 문자시작기호 필수
(?:
   [0-9]{2}                      # YY
   (?:
      0[1-9]|1[0-2]              # MM
   )
   (?:
      0[1-9]|[1,2][0-9]|3[0,1]   # DD
   )
)
-                                # 중간 연결자 하이픈
[1-8][0-9]{6}                    # 첫번째 1자리 1~4 내국인 5~8 외국인
$                                # 주민번호 종료
"""

re.search(jumin_p, "841225-12345678", re.X)
Out[1]: <re.Match object; span=(0, 14), match='841225-1234567'>

re.search(jumin_p, "841225-12345678", re.X) # None - 자리수 오버
re.search(jumin_p, "841225-9234567", re.X)  # None - 19세기 출생자

 

반응형