>>> # 기본
>>> import re
>>> 
>>> str = '010-1111-2222'
>>> ptn = r'\d\d\d-\d\d\d\d-\d\d\d\d' # 정규표현식 지정
>>> 
>>> if re.match(ptn, str) : # str이 정규표현식(ptn)과 맞는지 검사
>>>     print('{} is phone number', str)
>>> else :
>>>     print('{} is not phone number', str)
>>> 
>>> # fullmatch
>>> str = 'abc'
>>> ptn = r'ab'
>>> re.match(ptn, str) # True
>>> re.fullmatch(ptn, str) # False : 문장 전체가 맞아야 True 반환
>>>
>>> # 첫문자열 부터 검사하며 한번 일치 한 뒤에는 어떤 문자가 와도 상관없음
>>> bool(re.match(r'\d', '3')) 		# True
>>> bool(re.match(r'\d', '3aaa')) 	# True
>>> bool(re.match(r'\d', 'aaa3')) 	# False

 

 

1. 컴파일 vs 실행

- 정규표현식은 2개의 프로세스로 나뉜다 > 컴파일, 실행

  • 컴파일 : 패턴을 일괄적으로 상태기계로 불리는 열거형 데이터 구조로 만듬
  • 실행 : 일치 유무를 판단. 프로그램이 상태기계를 순회하면서 일치를 찾는다.

- re.compile : 정규표현식을 컴파일한다. 
- re.match에 r'문자열'을 인수로 넣으면 호출마다 컴파일+실행 이 되지만(상태기계를 매번 만들어야 한다), re.compile로 미리 표현식을 컴파일 해 놓으면 실행만 동작한다.

>>> import re
>>> 
>>> reg1 = re.compile(r'ca*b$')
>>> 
>>> def test_item(s) :
>>>     if re.match(reg1, s) :
>>>         print(s, 'is a match.')
>>>     else :
>>>         print(s, 'is not a match.')
>>> 
>>> test_item('caab')
>>> test_item('caaxxb')

- 위 코드의 경우 컴파일 1번 실행 2번을 거치게 된다.

 

 

2. 플래그
>>> if re.match('m*ack', 'Mack the Knife', re.IGNORECASE | re.DEBUG) :
>>>     print('Success.')

- '|'를 써서 플레그를 중첩 시킬 수 있다.

 

 

3. 문법

[ 메타문자 ]

 

[ 문자집합 ]

[abc] 	# abc 중 하나
[^abc] 	# abc 아닌것 중 하나
[A-Z] 	# A-Z 중 하나
[+-*/] 	# +-*/ 중 하나, 특수문자 그대로 인식

- '^'는 [바로 다음에 올경우,  '-'은 문자사이에 위치하는 경우 외에는 일반 문자 취급
- 어디에서든 일반문자로 취급하려면 ₩사용

 

[ 패턴 수량자 ]

[ 실습예제 ]

암호에 다음 규칙을 검사하라.

 

1. 모든 문자는 대문자 혹은 소문자, 숫자 혹은 언더스코어(_), 혹은 구두접 문자(@, #, $, %, ^, &, *. !)다.
2. 최소 8자
3. 최소한 글자 1개 포함
4. 최소한 숫자 1개 포함
5. 최소한 구두점 문자 1개 포함

 

>>> import re
>>> 
>>> pat1 = r'(\w|[@#$%^&*!]){8,}$' 	# 1, 2번 조건
>>> pat2 = r'.*\d' 					# 4번 조건
>>> pat3 = r'.*[a-zA-Z]'			# 3번 조건
>>> pat4 = r'.*[@#$%^&*!]'			# 5번 조건
>>> 
>>> def verify_passwd(s) :
>>>     b = (re.match(pat1, s) and re.match(pat2, s) and
>>>             re.match(pat3, s) and re.match(pat4, s) )
>>>     return bool(s)

 

4. Match 객체 사용

>>> import re
>>> 
>>> pat = r'(a+)(b+)(c+)'
>>> m = re.match(pat, 'abbccceeee')
>>> 
>>> for i in range(m.lastindex + 1) : 	# lastindex=3
>>> 	print(i, '. ', m.group(i), sep='')
>>> 
	0. abbccc
	1. a
	2. bb
	3. ccc

 

5. search

- 패턴의 문자열에 대한 포함 여부 검색.

- match와 달리 검색 문자열의 첫문자부터 일치하지 않아도 된다.

>>> import re
>>> m = re.search(r'\d{2,}', '1 set of 23 owls, 999 doves.')
>>> print('"', m.group(), '" found at ', m.span(), sep='')
	"23" found at (9, 11)

- 패턴에 맞는 문자열 "23"을 찾았고 위치는 9~11번 인덱스사이에 있다.

 

 

6. findall

- 대상_문자열 에서 패턴에 해당하는 모든 결과를 리스트로 반환

>>> import re
>>> s = 'What is 1,000.5 times 3 times 2,000?'
>>> print(re.findall(r'\d[0-9,.]*', s))
	[ '1,000.5', '3', '2,000' ]

 

[ findall 그룹화 오류 ] 

>>> pat = r'\d{1,3}(,\d{3})*(\.\d)?' # 숫자 미국 표준 포맷 
>>> print(re.findall(pat, '12,000 monkeys and 55.5 cats.'))
	[ (',000', ''), ('', '.5') ]

- 예상된 결과(12,000, 55.5)와 다르다
- pat의 ()가 그룹화로 인식 되었기 때문. 이는 다음과 같이 동작한다.
    1. pat에 맞는 문자열 인식 '12,000'
    2. 1번째 그룹패턴 인식 > ',000'
    3. 2번째 그룹패턴 인식 > 없음
    4. 1,2번 그룹을 튜플로 묶어 출력
- match객체에서의 0번째는 전체 패턴 결과를 출력하지만 여기선 그건 없는 것 같음.

>>> pat = r'(\d{1,3}(,\d{3})*(\.\d)?)' # 숫자 미국 표준 포맷 
>>> st = re.findall(pat, '12,000 monkeys and 55.5 cats.')
>>> for item in st :
... 	print(item[0])
	12,000
	55.5

- 패턴 전체를 그룹화 하면 전체패턴이 1번째 그룹으로 인식되어 0번인덱스에 원하는 결과가 출력된다.

 

 

7. 반복패턴
>>> import re
>>> 
>>> str = 'The cow jumped over the the moon Moon.'
>>> m = re.search(r'(\w) \1', str) # \1 : (\w)로 찾은 것과 동일한 단어
>>> print(m.group(), '...found at', m.span())
	the the ...found at (20, 27)
    
>>> # flag 사용
>>> m = re.search(r'(\w) \1', str, flags=re.I) # re.IGNORECASE : 대소문자 무시
	moon Moon ...found at (28, 37)

- \숫자 : 그룹을 지칭. 해당 그룹에 매칭된 문자열과 동일한(패턴X, 내용O) 문자열을 검색

 

 

8. 교체하기

>>> import re
>>> s1 = 'Get me a new dog to befriend my dog.'
>>> s2 = re.sub('dog', 'cat', s1)
>>> print(s2)
	Get me a new cat to befriend my cat.
>>> 
>>> # 반복패턴
>>> s1 = 'The the cow jumped over over the moon.'
>>> s2 = re.sub('(\w+) \1', '\1', s1, flags=re.I)
>>> print(s2)
	The cow jumped over the moon.

 

 

 

 

 

'Python > 공통이론' 카테고리의 다른 글

Python - 파일 / 디렉터리 시스템  (0) 2023.05.23
Python - 고급 정규표현식  (0) 2023.05.05
Python - format 함수&메서드의 사양 필드  (0) 2023.04.17
Python - repr  (0) 2023.04.17
Python - format 메서드  (0) 2023.04.14

+ Recent posts