정규표현식이란?
정규표현식이란?
- 복잡한 문자열을 처리할 때 사용하는 기법, 모든 언어 공통
ex) 주민등록번호의 뒷자리를 *문자로 변경하기
import re
data = """
park 800905-1049119
kim 700905-1059112
"""
pat = re.compile("(\d{6})[-]\d{7}")
print(pat.sub("\g<1>-*******"),data)
문자 클래스[ ]
[abc]
- [] 사이의 문자들과 매치
- "a"는 정규식과 일치하는 문자인 "a"가 있으므로 매치
- "before"는 정규식과 일치하는 문자인 "b"가 있으므로 매치
- "dude"는 정규식과 일치하는 문자인 a,b,c 중 어느 하나도 포함하고 있지 않으므로 매치 X
- 하이픈을 사용하여 From-To로 표현 가능
ex) [a-c] = [abc], [0-5] = [012345]
Dot(.)
a.b
- 줄바꿈(\n)을 제외한 모든 문자와 매치
- "aab"는 가운데 문자 "a"가 모든 문자를 의미하는 '.'과 일치하므로 정규식과 매치
- "a0b"는 가운데 문자 "0"가 모든 문자를 의미하는 '.'과 일치하므로 정규식과 매치
- "abc"는 "a"문자와 "b"문자 사이에 어떤 문자라도 하나는 있어야 하는 이 정규식과 일치하지 않으므로 매치 X
반복 (*)
ca*t
- "ct"는 "a"가 0번 반복되어 매치
- "cat"는 "a"가 0번 이상 반복되어 매치 (1번 반복)
- "caaat"는 "a"가 0번 이상 반복되어 매치 (3번 반복)
반복 (+)
ca+t
- "ct"는 "a"가 0번 반복되어 매치되지 않음
- "cat"는 "a"가 1번 이상 반복되어 매치 (1번 반복)
- "caaat"는 "a"가 1번 이상 반복되어 매치 (3번 반복)
반복 ({m,n},?)
ca{2}t
- "cat"는 "a"가 1번만 반복되어 매치되지 않음
- "caat"는 "a"가 2번 반복되어 매치
ca{2,5}t
→ a 2이상 5이하
- "cat"는 "a"가 1번만 반복되어 매치되지 않음
- "caat"는 "a"가 2번 반복되어 매치
- "caaaaat"는 "a"가 5번 반복되어 매치
ab?c
→ b가 0회 혹은 1회
- "abc"는 "b"가 1번 사용되어 매치
- "ac"는 "b"가 0번 사용되어 매치
? == {0,1}와 같은 표현
정규 표현식 시작하기
파이썬에서 정규 표현식을 지원하는 re 모듈
import re
p = re.compile('ab*')
→ p는 패턴 객체
① match
import re
p = re.compile('[a-z]+')
m = p.match('3 python')
print(m)
→ NONE
② search
import re
p = re.compile('[a-z]+')
m = p.search('3 python')
print(m)
출력
③ findall
import re
p = re.compile('[a-z]+')
m = p.findall('life is too short')
print(m)
출력
④ finditer
import re
p = re.compile('[a-z]+')
m = p.finditer('life is too short')
print(m)
출력
import re
p = re.compile('[a-z]+')
m = p.finditer('life is too short')
for r in m:
print(r)
출력
※ match 객체의 메서드1
method | 목적 |
group | 매치된 문자열을 리턴한다. |
start | 매치된 문자열의 시작 위치를 리턴한다. |
end | 매치된 문자열의 끝 위치를 리턴한다. |
span | 매치된 문자열의 (시작, 끝)에 해당하는 튜플을 리턴한다. |
import re
p = re.compile('[a-z]+')
m = p.match('python')
print(m.group())
print(m.start())
print(m.end())
print(m.span())
출력
(0,6) → 튜플
컴파일 옵션, DOTALL, S
→ 줄바꿈 문자도 포함시킴
ex1)
# DOTALL, S
import re
p = re.compile('a.b')
m = p.match('a\nb')
print(m)
→ NONE
ex2)
# DOTALL, S
import re
p = re.compile('a.b', re.DOTALL)
m = p.match('a\nb')
print(m)
출력
IGNORECASE, I
# IGNORECASE, I
import re
p = re.compile('[a-z]', re.I)
print(p.match('python'))
print(p.match('Python'))
print(p.match('PYTHON'))
출력
MULTILINE, M
ex1)
# MULTILINE, M
import re
p = re.compile("^python\s\w+") #^는 맨 처음, \s는 공백, \w는 알파벳,숫자, _중의 한 문자
data = """python one
life is too short
python two
you need python
python three"""
print(p.findall(data))
출력
ex2)
# MULTILINE, M
import re
p = re.compile("^python\s\w+", re.MULTILINE)
data = """python one
life is too short
python two
you need python
python three"""
print(p.findall(data))
출력
VERBOSE, X
#VERBOSE, X
import re
charref = re.compile(r'&[#](0[0-7]+|[0-9]+|x[0-9a-fA-F]+);')
charref = re.compile(r"""
&[#] #Start of a numeric entity reference
(
0[0-7]+ #Octal form
|[0-9]+ #Decimal form
|x[0-9a-fA-F]+ #Hexadecimal form
)
; #Trailing semicolon
""",re.VERBOSE)
→ 정규표현식의 줄을 나누더라도 인식되도록 해줌
백슬래시 문제
\section
p = re.compile('\\\\section')
p = re.compile(r'\\section')
→ r을 붙이면 \\\\ 네 번을 안 써도 됨
강력한 정규 표현식의 세계로
메타문자 |
#메타문자 |
import re
p = re.compile('Crow|Servo')
m = p.match('CrowHello')
print(m)
→ | or
출력
메타문자 ^
#메타문자 |
import re
print(re.search('^Life', 'Life is too short'))
print(re.search('^Lift', 'My Life'))
→ ^ 맨 처음에 나오는지
출력
그루핑 ()
ex1)
#그루핑 ()
import re
p = re.compile('(ABC)+')
m = p.search('ABCABCABC OK?')
print(m)
print(m.group())
→ ABC를 묶을 땐 (ABC)로
ex2)
#그루핑 ()
import re
p = re.compile(r'(\b\w+)\s+\1')
print(p.search('Paris in the the spring').group())
→ \1 한번 더 있는 것을 찾아낸다
출력
ex3) ?P<name>
#그루핑 ()
import re
p = re.compile(r"(?P<name>\w+)\s+((\d+)[-]\d+[-]\d+)")
m = p.search("park 010-1234-1234")
print(m.group("name"))
→ <name>으로 된 것을 분류할 수 있다
출력
ex4) (?P=word)
#그루핑 ()
import re
p = re.compile(r'(?P<word>\b\w+)\s+(?P=word)')
print(p.search('Paris in the the spring').group())
출력
전방탐색: 긍정형 (?=)
#전방탐색: 긍정형 (?=)
import re
p = re.compile(".+:")
m = p.search("http://google.com")
print(m.group())
출력
: 을 빼려면?
#전방탐색: 긍정형 (?=)
import re
p = re.compile(".+(?=:)")
m = p.search("http://google.com")
print(m.group())
→ ?= 뒤에 전방탐색의 기준이 될 문자 삽입
출력
전방탐색: 부정형 (?!)
문자열 바꾸기 sub
#문자열 바꾸기 sub
import re
p = re.compile('(blue|white|red)')
m = p.sub('colour', 'blue socks and red shoes')
print(m)
→ blue,white,red 중에 포함된 게 있다면 colour로 치환
출력
Geedy vs Non-Greedy
import re
s = '<html><head><title>Title</title>'
print(re.match('<.*>',s).group()) #Greedy
print(re.match('<.*?>',s).group()) #Non-Greedy
출력
※ 해당 게시글은 개인 학습의 목적으로, 아래 강의를 수강한 후 정리한 학습노트입니다.
https://www.youtube.com/watch?v=dTDoTR0MXjU&list=PLU9-uwewPMe2AX9o9hFgv-nRvOcBdzvP5&index=10
'Python 프로그래밍 > 기초 문법' 카테고리의 다른 글
[점프 투 파이썬] 6강: 파이썬 프로그래밍, 어떻게 시작해야 할까? (0) | 2024.06.12 |
---|---|
[점프 투 파이썬] 5강: 파이썬 날개 달기 (0) | 2024.06.11 |
[점프 투 파이썬] 4강: 파이썬의 입출력 (0) | 2024.06.11 |
[점프 투 파이썬] 3강: 프로그램의 구조를 쌓는다! 제어문 (0) | 2024.06.10 |
[점프 투 파이썬] 2강: 파이썬 프로그래밍의 기초, 자료형(2) (0) | 2024.06.09 |