1. 정규 표현식
복잡한 문자열을 처리할 때 사용하는 기법, 줄여서 정규식이라고도 말한다.
주민번호 뒷자리를 바뀔 때 *이 나오는 것을 정규식으로 표현할 수 있다.
1) 시작
(1) 메타 문자
원래 그 문자가 가긴 뜻이 아니라 특별한 의미를 가진 문자를 의미
- . ^ $ * + ? { } [ ] \ | ( )
(2) [ ] 문자 클래스
문자 클래스로 만들어진 정규식은 '[' 와 ']' 사이의 문자들과 매치라는 의미
- 문자 클래스를 만드는 메타 문자인 [ ] 사이에는 어떤 문자도 들어갈 수 있다.
- 정규식이 [abc]라면 'a, b, c" 중 한 개의 문자와 매치라는 뜻이다.
정규식 | 문자열 | 매치 여부 | 설명 |
[abc] | a | O | "a"는 정규식과 일치하는 문자인 "a"가 있으므로 매치 |
before | O | "before"는 정규식과 일치하는 문자인 "b"가 있으므로 매치 | |
dude | X | "dude"는 정규식과 일치하는 문자인 a, b, c 중 어느 하나도 포함하고 있지 않으므로 매치되지 않음 |
(3) - 문자 클래스
[ ] 안의 두 문자 사이에 하이픈(-)을 사용하면 두 문자 시이의 범위를 의미
- [a-c]는 [abc], [0-5]는 [012345]와 같다.
- [a-zA-Z]는 모든 알파벳 의미
- [0-9]는 모든 숫자
주의해야 할 메타 문자는 ^이다. 문자 클래스 안에 ^ 메타 문자를 사용할 경우에는 반대(not)라는 의미를 갖는다.
[^0-9]라는 정규식은 숫자가 아닌 문자만 매치된다.
- 자주 사융하는 문자 클래스
정규 표현식 | 설명 |
\d | 숫자와 매치, [0-9]와 동일한 표현식 |
\D | 숫자가 아닌 것과 매치, [^0-9]와 동일한 표현식 |
\s | 화이트스페이스 문자와 매치, [ \t\n\r\f\v]와 동일한 표현식, 맨 앞의 빈칸은 공백 문자(space)를 의미 |
\S | 화이트스페이스 문자가 아닌 것과 매치, [^ \t\n\r\f\v]와 동일한 표현식 |
\w | 문자 + 숫자와 매치, [a-zA-Z0-9_]와 동일한 표현식 |
\W | 문자 + 숫자가 아닌 문자와 매치 [^a-zA-Z0-9_]와 동일한 표현식 |
- 화이트스페이스 문자란 스페이스, 탭, 줄바꿈과 같은 공백 문자를 의미
(4) .[dot] 문자 - \n을 제외한 모든 문자
정규식 .(dot) 메타 문자는 줄 바꿈인 \n을 제외한 모든 문자와 매치
- a.b는 "a + 모든_문자 + b"를 의미
- a와 b라는 문자 사이에 어떤 문자가 들어가도 모두 매치된다는 의미
정규식 | 문자열 | 매치 여부 | 설명 |
a.b | aab | O | "aab"는 가운데 문자 "a"가 모든 문자를 의미하는 .과 일치하므로 정규식과 매치 |
a0b | O | "a0b"는 가운데 문자 "0"가 모든 문자를 의미하는 .과 일치하므로 정규식과 매치 | |
abc | X | "abc"는 "a" 문자와 "b" 문자 사이에 어떤 문자라도 하나는 있어야 하는 이 정규식과 일치하지 않으므로 매치되지 않음 |
a[.]b처럼 [ ] 안에 . 문자를 쓰면 '.' 문자 그대로를 의미한다. 이 정규식의 의미는 "a + . + b"가 된다.
따라서 정규식 a[.]b는 "a.b" 문자열과 매치되고 "a0b" 문자열과는 매치되지 않는다.
(5) * 문자
*은 바로 앞에 있는 문자가 0부터 무한대까지 반복될 수 있다는 의미
- * 메터 문자의 박복 개수가 무한대라고 했지만, 메모리 용량에 한계가 있어 실제로는 약 2억 개라고 한다.
정규식 | 문자열 | 매치 여부 | 설명 |
ca*t | ct | O | "a"가 0번 반복되어 매치 |
cat | O | "a"가 0번 이상 반복되어 매치(1번 반복) | |
caaat | O | "a"가 0번 이상 반복되어 매치(3번 반복) |
(6) + 문자
+는 최소 1번 시상 반복될 때 사용
정규식 | 문자열 | 매치 여부 | 설명 |
ca+t | ct | X | "a"가 0번 반복되어 매치되지 않음 |
cat | O | "a"가 1번 이상 반복되어 매치(1번 반복) | |
caaat | O | "a"가 1번 이상 반복되어 매치(3번 반복) |
(7) { } 문자
반복 횟수를 고정할 수 있는 문자
- {M}
정규식 | 문자열 | 매치 여부 | 설명 |
ca[2]t | cat | X | "a"가 1번만 반복되어 매치되지 않음 |
caat | O | "a"가 2번 반복되어 매치 |
앞 문자를 반드시 2번 반복을 의미
- {m, n}
정규식 | 문자열 | 매치 여부 | 설명 |
ca[2, 5]t | cat | X | "a"가 1번만 반복되어 매치 되지 않음. |
caat | O | "a"가 2번 반복되어 매치 | |
caaaaat | O | "a"가 5번 반복되어 매치 |
앞 문자를 2~5화 반복
(8) ? 문자
? 메타 문자는 {0,1}을 의미
정규식 | 문자열 | 매치 여부 | 설명 |
ab?c | abc | O | "b"가 1번 사용되어 매치 |
ac | O | "b"가 0번 사용되어 매치 |
- "a + b가_있어도_되고_없어도_됨+ c"
- b 문자가 있거나 없거나 둘 다 매치되는 경우
2) re모듈
정규 표현식을 지원하기 위해 re 모듈을 제공
import re
p = re.compile('ab*')
3) 정규식을 이용한 문자열 검색
메서드 | 목적 |
match | 문자열의 처음부터 정규식과 매치되는지 조사 |
search | 문자열 전체를 검색하여 정규식과 매치되는지 조사 |
findall | 정규식과 매치되는 모든 문자열을 리스트로 리턴 |
finditer | 정규식과 매치되는 모든 문자열을 이터레이터 객체로 리턴 |
(1) match
정규식과 100% 일치하면 리턴, 일치하지 않으면 None 리턴
import re
p = re.compile('[a-z]+') # 소문자가 한 번 이상 나오는 것
m = p.match('python')
print(m)
- 출력 : <re.Match object; span=(0, 6), match='python'>
import re
p = re.compile('[a-z]+') # 소문자가 한 번 이상 나오는 것
m = p.match('3 python')
print(m)
- 처음에 나오는 문자 3이 정규식에 부합되지 않으므로 None 리턴
- match 객체의 메서드
메서드 | 목적 |
group | 매치된 문자열을 리턴 |
start | 매치된 문자열의 시작 위치를 리턴 |
end | 매치된 문자열의 끝 위치를 리턴 |
span | 매치된 문자열의 (시작, 끝)에 해당하는 튜플을 리턴 |
(2) search
문자열을 검색해 일치하는 문자열이 있으면 문자열을 리턴
import re
p = re.compile('[a-z]+') # 소문자가 한 번 이상 나오는 것
m = p.search('python')
print(m)
- 출력 : <re.Match object; span=(0, 6), match='python'>
위 match와 동일한 출력을 한다.
import re
p = re.compile('[a-z]+') # 소문자가 한 번 이상 나오는 것
m = p.search('3 python')
print(m)
- 출력 : <re.Match object; span=(2, 8), match='python'>
search는 문자열의 처음부터 검색하는 것이 아니라 문자열 전체를 검색하기 때문에 "3" 이수의 "python" 문자열가 매치
(3) findall
매치되는 모든 값을 찾아 리턴
import re
p = re.compile('[a-z]+') # 소문자가 한 번 이상 나오는 것
result = p.findall('life is too short')
print(result)
- 출력 : ['life', 'is', 'too', 'short']
(4) finditer
findall과 동일하지만, 그 결과로 이터레이터 객체를 리턴
이터레이터 객체가 포함하는 각각의 요소는 match 객체
import re
p = re.compile('[a-z]+') # 소문자가 한 번 이상 나오는 것
result = p.finditer('life is too short')
for r in result : print(r)
- 출력 : <re.Match object; span=(0, 4), match='life'>
- 출력 : <re.Match object; span=(5, 7), match='is'>
- 출력 : <re.Match object; span=(8, 11), match='too'>
- 출력 : <re.Match object; span=(12, 17), match='short'>
4. 컴파일 옵션
옵션 이름 | 약어 | 설명 |
DOTALL | S | .(dot)이 줄 바꿈 문자를 포함해 모든 문자와 매치될 수 있게 한다. |
IGNORECASE | I | 대소문자에 관계없이 매치될 수 있게 한다. |
MULTILINE | M | 여러 줄과 매치될 수 있게 한다. ^, $ 메타 문자 사용과 관계있는 옵션 |
VERBOSE | X | verbose 모드를 사용할 수 있게 한다. 정규식을 보기 편하게 만들 수 있고 주석 등을 사용할 수 있게 된다. |
1) DOTALL, S
. 메타 문자는 줄 바꿈 문자(\n)를 제외한 모든 문자와 매치되는 규칙이 있다. \n 문자도 포함하여 매치하고 싶다면 re.DOTALL 또는 re.S 옵션을 사용하면 된다.
import re
p = re.compile('a.b', re.DOTALL)
m = p.match('a\nb')
print(m)
- 출력 : <re.Match object; span=(0, 3), match='a\nb'>
- 여러 줄로 이루어진 문자열에서 줄 바꿈 문자에 상관없이 검색할 때 사용
2) IGNORECASE, I
대소문자 구별 없이 매치를 수행할 때 사용하는 옵션
import re
p = re.compile('[a-z]+', re.I)
print(p.match('python'))
print(p.match('Python'))
print(p.match('PYTHON'))
- [a-z]+ 정규식은 소문자만을 의미하지만, re.I 옵션으로 대소문자 구별 없이 매치
- 모든 문자열이 매치돼 출력됨
3) MULTILINE, M
^, $와 연관된 옵션
- ^는 문자열의 처음을 의미
- $는 문자열의 마지막을 의미
정규식이 ^python이면, 문자열의 처음은 항상 python으로 시작해야 매치되고, 정규식이 python$이면 문자열의 마지막은 항상 python으로 끝나야 매치된다는 의미다.
import re
p = re.compile('^python\s\w+')
data = """python one
life is too short
python two
you need python
python three"""
print(p.findall(data))
- 출력 : ['python one']
- ^python\s\w+는 python이라는 문자열로 시작하고 그 뒤에 화이트스페이스, 그 뒤에 단어가 와야 한다는 의미
- ^ 메타 문자에 의해 python이라는 문자열을 사용한 첫 번째 줄만 매치
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))
- 출력 : ['python one', 'python two', 'python three']
- MULTILINE 옵션으로 인해 ^ 메타 문자가 문자열 전체가 아닌 각 줄의 처음이라는 의미를 가짐
4) VERBOSE, X
정규식을 주석 또는 줄 단위로 구분하는 옵션
import re
charref = re.compile(r"""
&[#] # Start of a numeric entity reference
(
0[0-7]+ # Octal form 8진수
| [0-9]+ # Decimal form 10진수
| x[0-9a-fA-F]+ # Hexadecimal form 16진수
)
; # Trailing semicolon
""", re.VERBOSE)
- 정규식이 복잡할 경우, 주석을 적고 여러 줄로 표현하는 것이 훨씬 가독성이 좋다.
- VERBOSE 옵션을 사용하면 문자열에 사용된 화이트스페스는 컴파일할 때 제거
- 단, [ ] 안에 사용한 화이트스페이스는 제외
'SK Shieldus Rookies 19th > 인프라 활용을 위한 파이썬' 카테고리의 다른 글
[SK shieldus Rookies 19기][SQL] - SQL (0) | 2024.03.19 |
---|---|
[SK shieldus Rookies 19기][SQL] - 실습 환경 구성 (1) | 2024.03.19 |
[SK shieldus Rookies 19기][Python] - 내장 함수, 표준 라이브러리, 외부 라이브러리 Faker (0) | 2024.03.18 |
[SK shieldus Rookies 19기][Python] - 클래스, 모듈, 패키지, 오류 처리 (7) | 2024.03.18 |
[SK shieldus Rookies 19기][Python] - 실습 2 (0) | 2024.03.17 |
댓글