복잡한 문자열을 처리할 때 사용하는 기법으로, 모든 언어에 공통적으로 사용됨
코드를 간결하게 작성하기 위함
ex) 주민등록번호의 뒷자리를 * 문자로 변경
어떤 문자열의 규칙을 찾아 조건을 만족할 시 변경하라는 문제에 주로 쓰임
[]
사이의 문자들과 매치
정규표현식 ex) [abc]
"a"는 정규식과 일치하는 문자인 "a"가 있으므로 매치,
"before"는 정규식과 일치하는 문자인 "b"가 있으므로 매치,
"dude"는 정규식과 일치하는 문자를 포함하지 않으므로 매치되지 않음
💡 하이픈(-)
을 사용하여 From-To
로 표현 가능
ex) [a-c] = [abc], [0-5] = [012345]
.
을 사용하면 줄바꿈(\n)을 제외한 어떠한 문자라도 존재해야함
정규표현식 ex) a.b
"aab"는 가운데 문자 "a"가 모든 문자를 의미하는 '.'과 일치하므로 정규식과 매치,
"a0b"는 가운데 문자 "0"가 모든 문자를 의미하는 '.'과 일치하므로 정규식과 매치,
"abc"는 "a" 문자와 "b" 문자 사이에 어떤 문자라도 있어야하는데 없으므로 매치되지 않음
*
바로 앞 문자가 여러 번(0번 이상) 반복되는 표현
이 때0번 반복
되어도 매치
정규표현식 ex) ca*t
"ct"는 "a"가 0번 반복되므로 매치,
"cat"는 "a"가 1번 반복되므로 매치
"caaat"는 "a"가 3번 반복되므로 매치
+
바로 앞 문자가 여러 번(1번 이상) 반복되는 표현
*는 0번 반복되어도 매치되지만, +는 0번 반복은 매치되지 않음
정규표현식 ex) ca+t
"ct"는 "a"가 0번 반복되므로 매치되지 않음,
"cat"는 "a"가 1번 반복되므로 매치,
"caaat"는 "a"가 3번 반복되므로 매치
{m}
또는{m,n}
으로 사용해 앞의 문자 반복
{m}의 경우 해당 숫자만큼 반복되어야 매치되고, {m,n}의 경우 m이상 n이하만큼 반복되야 매치됨
정규표현식 ex) ca{2}t
"cat"는 "a"가 1번 반복되므로 매치되지 않음
"caat"은 "a"가 2번 반복되므로 매치됨
정규표현식 ex) ca{2,4}t
"cat"은 "a"가 1번 반복되므로 매치되지 않음
"caat"은 "a"가 2번 반복되어 매치
"caaaaat"는 "a"가 5번 반복되어 매치
?
를 사용해 앞의 문자를 0번 또는 1번 반복
? == {0,1} 과 같은 의미
정규표현식 ex) ab?c
"abc"는 "b"가 1번 반복되므로 매치
"ac"는 "b"가 0번 반복되므로 매치
파이썬에서 정규표현식 지원
p라는 객체를 만들어 사용
사용예시
import re
p = re.compile('정규표현식')
매치가 될 경우 match객체 m을 돌려주고, 매치가 되지 않을 경우 None return
import re
p = re.compile('[a-z]+') #a로 시작하고 z로 끝나는 문자가 1번 이상 반복되면 매치
m = p.match('python') #match 객체 m을 만들어주고 match() 내에 검사하고자 하는 문자열을 넣음
print(m)
첫번째가 일치하지 않아도 일치하는 구문이 있다면 그 문자를 match객체 m으로 받아 return
import re
p = re.compile('[a-z]+')
m = p.search('python') #일치하는 구문을 m으로 받아 return
print(m)
매치되는 구문을 찾아 list로 return
import re
p = re.compile('[a-z]+')
m = p.findall('life is too short')
print(m)
m만 출력할 경우 iterator object가 출력되어 for문으로 출력해야함
for문으로 출력할 경우 match 객체 출력
import re
p = re.compile('[a-z]+')
m = p.finditer('life is too short')
for r in m:
print(r)
method | 목적 |
---|---|
group() | 매치된 문자열을 리턴 |
start() | 매치된 문자열의 시작 위치(index) 리턴 |
end() | 매치된 문자열의 끝 위치(index) 리턴 |
span() | 매치된 문자열의 (시작,끝)에 해당하는 튜플 리턴 |
import re
p = re.compile('[a-z]+')
m = p.match('python')
print(m.group()) #python 출력
print(m.start()) #0 출력
print(m.end()) #6 출력
print(m.span()) #(0,6) 출력
p 객체를 만들 때 옵션으로 선택해 넣어 기능을 추가
기존 dot(.)은 \n이 불가능하지만 이를 가능하게 해줌
re.DOTALL == re.S
import re
p = re.compile('a.b', re.DOTALL)
m = p.match('a\nb')
print(m)
기존에는 표현식 내의 대소문자를 구별하여 사용하지만 대소문자를 무시하도록해줌
import re
p = re.compile('[a-z]+', re.I)
print(p.match('python'))
print(p.match('Python'))
print(p.match('PYTHON'))
꺽쇄(^)를 맨 처음만이 아니라 각 라인에 적용시키도록 함
import re
p = re.compile("^python\s\w+", re.M) #^는 맨 처음에 나오는 문자, \s는 공백, \w는 알파벳, 숫자,_중의 한 문자 의미
data = """python one
life is too short
python two
you need python
python three"""
print(p.findall(data)) #3번찍힘
긴 정규표현식을 나눠서 쓸 수 있게 만들어주는 옵션
import re
charref = re.compile(r'&[#](0[0-7]+|[0-9]+|x[0-9a-fA-F]+);') #1 아래와 동일 코드
charref = re.compile(r""" #2 위와 동일 코드
&[#]
(
0[0-7]+
|[0-9]+
|x[0-9a-fA-F]+
)
;
""", re.VERBOSE)
백슬래시()는 정규표현식에 자주 쓰여 실제 백슬래시를 사용하고 싶을 경우 2개,
실제 백슬래시 2개를 사용하고 싶을 경우 4개를 사용해야함
이를 해결하기 위해 r'\'와 같이 r'' 사이의 백슬래시는 실제 백슬래시로 사용함
p = re.compile('\\section') #실제 백슬래시 1개
p = re.compile('\\\\section') #실제 백슬래시 2개
p = re.compile(r'\\section') #실제 백슬래시 2개로 사용
앞 또는 뒤 문자와 일치하면 매치
import re
p = re.compile('Crow|Servo')
m = p.match('CrowHello')
print(m)
^ 뒤에 나오는 문자가 맨 앞에 나오면 매치
import re
print(re.search('^Life', 'Life is too short')) #정규표현식과 찾을 문자를 한번에 작성할 수 있음
print(re.search('^Life', 'My Life'))
$ 뒤에 나오는 문자가 맨 뒤에 나오면 매치
import re
print(re.search('short$', 'Life is too short'))
print(re.search('short$', 'Life is too short, you need python'))
공백을 나타내며 표현식에 나타난 공백이 문자열에 나타난 공백과 일치할 경우 매치
import re
p = re.compile(r'\bclass\b')
print(p.search('no class at all'))
print(p.search('the declassified algorithm'))
print(p.search('one subclass is'))
괄호()를 이용해 표현식을 묶어줌
import re
p = re.compile('(ABC)+')
m = p.search('ABCABCABC OK?')
print(m)
print(m.group())