파이썬 - 정규표현식 기초 학습
정규표현식이란?
- 특정한 규칙을 가진 문자열의 집합을 표현하는데 사용하는 형식 언어
- 프로그래밍 언어 혹은 텍스트 에디터 등에서 문자열의 검색과 치환을 위한 용도로 사용
- 정규표현식에서 사용하는 기호를 메타 문자라고 한다.
- 메타 문자(meta characters) : 원래 그 문자가 가진 뜻이 아닌 표현식 내부에서 특정한 의미를 갖는 문자
- ex) . 6 $ * + ? { } [ ] \ | ( )
문자 클래스 [ ]
- 문자 클래스로 만들어진 정규식은 “ [ ] 사이의 문자들과 매치 “ 라는 의미를 갖는다.
- 예를 들어 [abc]는 “a, b, c 중 한개의 문자와 매치” 를 의미한다.
- “apple” –> 정규식과 일치하는 문자 “a”가 있으므로 매치
- “bottle” –> 정규식과 일치하는 문자 “b”가 있으므로 매치
- “dog” –> 정규식과 일치하는 문자 없으므로 매치되지 않음
- [ ] 안의 두 문자 사이에 하이픈(-)을 사용하면, 두 문자 사이의 범위(from-to) 를 의미한다.
- 정규표현식 [a-c]은 [abc]와 동일하고, [0-5]는 [012345]와 동일
- [a-zA-Z] : 알파벳(소문자/대문자) 모두
- [0-9] : 숫자
- [ ] 안에 ^ 메타 문자는, 반대(not)라는 의미를 갖는다.
- ^[0-9] : 숫자가 아닌 문자만 매치
- 자주 사용하는 문자 클래스
- ^ : 문자열 시작
- $ : 문자열 종료
- \d : 숫자와 매치
- \D : 숫자가 아닌 것과 매치, [^0-9]와 동일
- \s : whitespace 문자와 매치, [ \t\n\r\f\v]와 동일(맨 앞 빈 칸은 공백문자를 의미)
- \S : whitespace 문자가 아닌 것과 매치, [^ \t\n\r\f\v]와 동일
- \w : 문자+숫자와 매치, [a-zA-Z0-9_]와 동일
- \W : 문자+숫자가 아닌 것과 매치, [^a-zA-Z0-9_]와 동일
Dot(.)
- 정규표현식의 Dot(.) 메타 문자는 줄바꿈 문자인 \n를 제외한 모든 문자와 매치(옵션으로 re.DOTALL 옵션을 주면, \n 문자와도 매치)
- a.b 는 “a + 모든문자 + b”라는 의미
- ex) “aab”, “a0b”, “aAb” –> “a”와 “b”사이에 모든 문자를 의미하는 . 과 일치하므로 매치
- ex) “abc” –> “a”와 “b” 사이에 어떤 문자도 없으므로 매치되지 않음
- 주의 : a[.]b 는 “a + Dot(.)문자 + b”라는 의미
- “a.b” 문자열만 매치
반복(*)
- 의 의미는 바로 앞에 있는 문자가 최소 0번 이상 무한대로 반복될 수 있다는 것
- ex) ca*t –> “ct”, “cat”, “caaaat” 매치
반복(+)
- +의 의미는 + 바로 앞에 있는 문자가 최소 1번 이상 무한대로 반복될 수 있다는 것
- ex) ca+t –> “cat”, “caaaat” 매치
반복({m,n},?)
- {m,n}의 의미는 반복 횟수가 m부터 n까지인 것을 매치한다는 의미
- m 또는 n 생략 가능
- {3,} –> 반복 횟수 3번 이상인 경우
- {,3} –> 반복 횟수 3번 이하인 경우
- {3} –> 반복 횟수 3번인 경우
- {1,} 는 * 메타 문자와 동일
- {0,} 는 + 메타 문자와 동일
- {0, 1} 는 ? 메타 문자와 동일
- ab?c –> “a + b(있어도 되고 없어도 된다) + c”
- m 또는 n 생략 가능
파이썬에서 정규 표현식을 지원하는 re 모듈
- 파이썬은 정규 표현식을 지원하기 위해 re(regular expression의 약어) 모듈 제공
- re 모듈은 파이썬 설치될 때 자동 설치되는 기본 라이브러리
1
2import re
p = re.compile('ab*')
정규식 이용한 문자열 검색
- 컴파일 된 패턴 객체는 4가지 메소드 제공
- match() : 문자열 처음부터 정규식과 매치되는지 조사
- search() : 문자열 전체 검색하여 정규식과 매치되는지 조사
- findall() : 정규식과 매치되는 모든 문자열을 리스트로 리턴
- finditer() : 정규식과 매치되는 모든 문자열을 iterator 객체로 리턴
- match, search는 정규식과 매치 될 경우, match객체 리턴(매치되지 않을 경우 None 리턴)
match
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16import re
p = re.compile('[a-z]+')
m = p.match("python")
print(m) # <_sre.SRE_Match object at 0x01F3F9F8>
m = p.match("3 python")
print(m) # None
# "3 python" 문자열의 처음 문자인 3이 정규식 [a-z]+ 에 부합되지 않으므로 None 리턴
# 파이썬 정규식 프로그램은 보통 아래와 같은 흐름으로 작성
m = p.match('string goes here')
if m:
print('Match found: ', m.group())
else:
print('No match')search
1
2
3
4
5m = p.search("python")
print(m) # <_sre.SRE.Match object at 0x01F3FA68
m = p.search("3 python")
print(m) # <_sre.SRE.Match object at 0x01F3FA30>findall
1
2result = p.findall("life is too short")
print(result) # ['life', 'is', 'too', 'short']finditer
1
2
3
4
5
6
7
8result = p.finditer("life is too short")
print(result) # <callable_iterator object at 0x01F5E390>
for r in result:
print(r)
# <_sre.SRE_Match object at 0x01F3F9F8>
# <_sre.SRE_Match object at 0x01F3FAD8>
# <_sre.SRE_Match object at 0x01F3FAA0>
# <_sre.SRE_Match object at 0x01F3F9F8>- finditer는 findall과 동일하지만, 반복 가능한 객체(iterator object)를 리턴한다. (match 객체)
match 객체의 메서드
match 객체의 메서드
1
2
3
4
5m = p.match("python")
m.group() # 'python'
m.start() # 0
m.end() # 6
m.span() # (0, 6)- group() : 매치된 문자열 리턴
- start() : 매치된 문자열의 시작 위치 리턴
- end() : 매치된 문자열의 끝 위치 리턴
- span() : 매치된 문자열의 (시작, 끝)에 해당하는 튜플 리턴
re.compile 축약 방법
1
2
3
4
5p = re.compile('[a-z]+')
m = p.match("python")
# 컴파일과 match 메서드 한번에 수행
m = re.match('[a-z]+', "python")
컴파일 옵션
- 정규식을 컴파일할 때 아래와 같은 옵션 사용
- DOTALL(S) : 메타문자 . 이 줄바꿈 문자를 포함하여 모든 문자와 매치할 수 있도록 한다.
- IGNORECASE(I) : 대소문자 상관없이 매치
- MULTILINE(M) : 여러줄과 매치(^, $ 메타 문자 사용과 관계있는 옵션)
- VERBOSE(X) : verbose 모드 사용(정규식을 보기 편하게 만들고, 주석 등 사용 가능)
DOTALL,S (re.DOTALL 혹은 re.S)
1
2
3
4
5
6
7
8import re
p = re.compile('a.b')
m = p.match('a\nb')
print(m) # None
p = re.compile('a.b', re.DOTALL)
m = p.match('a\nb')
print(m) # <_sre.SRE_Match object at 0x01FCF3D8>IGNORECASE,I (re.IGNORECASE 혹은 re.I)
1
2
3
4p = re.compile('[a-z]', re.I)
p.match('python') # <_sre.SRE_Match object at 0x01FCFA30>
p.match('Python') # <_sre.SRE_Match object at 0x01FCFA68>
p.match('PYTHON') # <_sre.SRE_Match object at 0x01FCF9F8>MULTILINE,M (re.MULTILINE 혹은 re.M)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16import re
p = re.compile("^python\s\w+")
# ^ 메타 문자에 의해 python 문자열이 사용된 첫 번째 라인만 매치
data = """python one
life is too short
python two
you need python
python three"""
print(p.findall(data)) # ['python one']
# ^ 메타 문자를 문자열 전체가 아닌 각 라인의 처음으로 인식시키고 싶은 경우
p = re.compile("^python\s\w+", re.MULTILINE)
print(d.findall(data)) # ['python one', 'python two', 'python three']VERBOSE,X (re.VERBOSE 또는 re.X)
- 이해하기 어려운 정규식을 주석 또는 라인 단위로 구분하여 가독성있게 작성하고 싶을 때 사용
1
2
3
4
5
6
7
8
9
10
11charref = 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”이라는 문자열을 찾기 위한 정규식을 만들고 싶은 경우
\section에서 \s 문자가 whitespace로 해석되므로,
\\section
으로 변경하여 사용하여 이스케이프 처리를 한다.1
p = re.compile('\\section')
하지만, 실제 파이썬 정규식 엔진에는 파이썬 문자열 리터럴 규칙에 의하여
\\
이\
로 변경되어\section
이 전달된다.따라서, 파이썬은
\\\\
백슬래쉬 4개를 사용해야 한다.1
p = re.compile('\\\\section')
상기와 같은 문제를 해결하기 위해 파이썬 정규식에는 Raw string이 생겨났다.
즉, 컴파일해야 하는 정규식이 Raw String임을 알려줄 수 있도록 파이썬 문법이 만들어진 것
1
p = re.compile(r'\\section')
정규식 문자열 앞에 r 문자를 선행하면 이 정규식은 Raw String 규칙에 의해 백슬래시 2개 대신 1개만 써도 두개를 쓴 것과 동일한 의미를 가진다.
Posted
tags:
{ Python }
{ regular-expression }