[ ] 문자 클래스
[abc]
a, b, c 중 한 개의 문자와 매치
"a", "before", "dude"
=> 매치, 매치, 매치 안됨
[ ] 안의 두 문자 사이에 하이픈(-)을 사용하면 두 문자 사이의 범위(From - To)를 의미
[a-c] = [abc]
[0-5] = [012345]
- [a-zA-Z] : 알파벳 모두
- [0-9] : 숫자
- [^0-9] : 숫자가 아닌 모든 문자
- \d - 숫자와 매치, [0-9]와 동일
- \D - 숫자가 아닌 것과 매치, [^0-9]와 동일.
- \s - whitespace 문자와 매치, [ \t\n\r\f\v]와 동일. 맨 앞의 빈 칸은 공백문자(space)를 의미.
- \S - whitespace 문자가 아닌 것과 매치, [^ \t\n\r\f\v]와 동일.
- \w - 문자+숫자 (alphanumeric)와 매치, [a-zA-Z0-9_]와 동일.
- \W - 문자+숫자 (alphanumeric)가 아닌 문자와 매치, [^a-zA-Z0-9_]와 동일.
대문자로 사용된 것은 소문자의 반대
. Dot
줄바꿈 문자인 \n을 제외한 모든 문자와 매치
(re.DOTALL 옵션을 주면 \n 문자와도 매치된다)
a.b
"a + 모든문자 + b"
a와 b라는 문자 사이에 어떤 문자가 들어가도 모두 매치
"aab", "a0b", "abc"
=> 매치, 매치, 매치 안됨
* 0 이상 반복
ca*t
* 바로 앞에 있는 문자 a가 0부터 무한대로 반복될 수 있다는 의미
"ct", "cat","caaat"
=> 매치, 매치, 매치
+ 1 이상 반복
ca+t
"ct", "cat","caaat"
=> 매치안됨, 매치, 매치
반복횟수 지정 ({m,n}, ?)
{m, n} 정규식을 사용하면 반복 횟수가 m부터 n까지 매치
m 또는 n을 생략 가능 (생략된 m은 0과 동일하며, 생략된 n은 무한대(2억 개 미만)의 의미)
{3,}
반복 횟수가 3 이상
{,3}
반복 횟수가 3 이하
ca{2,5}t
문자 a가 2~5번까지 반복될 수 있다
"ct", "caat","caaat"
=> 매치안됨, 매치, 매치
? 메타문자가 의미하는 것은 {0, 1}
ab?c
a + b(있어도 되고 없어도 된다) + c
"ac", "abc"
=> 매치, 매치
re 모듈
import re
p = re.compile('ab*')
re.compile을 사용하여 정규 표현식(위 예에서는 ab*)을 컴파일한다. re.compile의 결과로 돌려주는 객체 p(컴파일된 패턴 객체)를 사용하여 그 이후의 작업을 수행
컴파일된 패턴 객체가 제공하는 4가지 메서드
match() | 문자열의 처음부터 정규식과 매치되는지 조사한다. |
search() | 문자열 전체를 검색하여 정규식과 매치되는지 조사한다. |
findall() | 정규식과 매치되는 모든 문자열(substring)을 리스트로 돌려준다. |
finditer() | 정규식과 매치되는 모든 문자열(substring)을 반복 가능한 객체로 돌려준다. |
match, search는 정규식과 매치될 때는 match 객체를 돌려주고, 매치되지 않을 때는 None을 돌려준다. (match 객체란 정규식의 검색 결과로 돌려주는 객체)
match()
import 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
"python" 문자열은 [a-z]+ 정규식에 부합되므로 match 객체를 돌려준다.
"3 python" 문자열은 처음에 나오는 문자 3이 정규식 [a-z]+에 부합되지 않으므로 None을 돌려준다.
match의 결과로 match 객체 또는 None을 돌려준다.
p = re.compile(정규표현식)
m = p.match( 'string goes here' )
if m:
print('Match found: ', m.group())
else:
print('No match')
search()
import re
p = re.compile('[a-z]+')
m = p.search("python")
print(m)
# <_sre.SRE_Match object at 0x01F3FA68>
m = p.search("3 python")
print(m)
# <_sre.SRE_Match object at 0x01F3FA30>
"python" 문자열에 search 메서드를 수행하면 match 메서드를 수행했을 때와 동일하게 매치
"3 python" 문자열의 첫 번째 문자는 "3"이지만 search는 문자열의 처음부터 검색하는 것이 아니라 문자열 전체를 검색하기 때문에 "3 " 이후의 "python" 문자열과 매치
findall()
import re
p = re.compile('[a-z]+')
result = p.findall("life is too short")
print(result)
# ['life', 'is', 'too', 'short']
"life is too short" 문자열의 'life', 'is', 'too', 'short' 단어를 각각 [a-z]+ 정규식과 매치해서 리스트로 돌려준다.
finditer()
import re
p = re.compile('[a-z]+')
result = 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 메서드와 search 메서드를 수행한 결과로 돌려준 match 객체
group() | 매치된 문자열을 돌려준다. |
start() | 매치된 문자열의 시작 위치를 돌려준다. |
end() | 매치된 문자열의 끝 위치를 돌려준다. |
span() | 매치된 문자열의 (시작, 끝)에 해당하는 튜플을 돌려준다. |
m = p.match("python")
m.group()
# 'python'
m.start()
# 0
m.end()
# 6
m.span()
# (0, 6)
m = p.search("3 python")
m.group()
# 'python'
m.start()
# 2
m.end()
# 8
m.span()
# (2, 8)
re.compile을 사용하여 컴파일된 패턴 객체로 그 이후의 작업을 수행할 수 있지만,
re 모듈은 이것을 좀 축약한 형태로도 사용할 수 있다.
p = re.compile('[a-z]+')
m = p.match("python")
m = re.match('[a-z]+', "python")
컴파일 옵션
- DOTALL(S) - . 이 줄바꿈 문자를 포함하여 모든 문자와 매치할 수 있도록 한다.
- IGNORECASE(I) - 대소문자에 관계없이 매치할 수 있도록 한다.
- MULTILINE(M) - 여러줄과 매치할 수 있도록 한다. (^, $ 메타문자의 사용과 관계가 있는 옵션이다)
- VERBOSE(X) - verbose 모드를 사용할 수 있도록 한다. (정규식을 보기 편하게 만들수 있고 주석등을 사용할 수 있게된다.)
옵션을 사용할 때는 re.DOTALL처럼 전체 옵션 이름을 써도 되고 re.S처럼 약어를 써도 된다.
DOTALL, S
. 메타 문자는 줄바꿈 문자(\n)를 제외한 모든 문자와 매치되는 규칙이 있다.
만약 \n 문자도 포함하여 매치하고 싶다면 re.DOTALL 또는 re.S 옵션을 사용해 정규식을 컴파일
import 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>
정규식이 a.b인 경우 문자열 a\nb는 매치되지 않음을 알 수 있다. 왜냐하면 \n은 . 메타 문자와 매치되지 않기 때문이다. \n 문자와도 매치되게 하려면 다음과 같이 re.DOTALL 옵션을 사용해야 한다.
보통 re.DOTALL 옵션은 여러 줄로 이루어진 문자열에서 \n에 상관없이 검색할 때 많이 사용
IGNORECASE, I
re.IGNORECASE 또는 re.I 옵션은 대소문자 구별 없이 매치를 수행할 때 사용하는 옵션
p = 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>
[a-z] 정규식은 소문자만을 의미하지만 re.I 옵션으로 대소문자 구별 없이 매치
MULTILINE, M
re.MULTILINE 또는 re.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이라는 문자열로 시작하고 그 뒤에 whitespace, 그 뒤에 단어가 와야 한다는 의미이다. 검색할 문자열 data는 여러 줄로 이루어져 있다.
^ 메타 문자에 의해 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']
re.MULTILINE 옵션으로 인해 ^ 메타 문자가 문자열 전체가 아닌 각 줄의 처음이라는 의미를 갖게 되었다.
re.MULTILINE 옵션은 ^, $ 메타 문자를 문자열의 각 줄마다 적용해 주는 것
정규식에서 '\section' 문자열을 찾기 위해서는
import re
p = re.compile(r'\\section')
정규식 문자열 앞에 r 문자를 삽입하면 이 정규식은 Raw String 규칙에 의하여 백슬래시 2개 대신 1개만 써도 2개를 쓴 것과 동일한 의미
출처
'Python > 점프 투 파이썬' 카테고리의 다른 글
파이썬 문자 자료형 (0) | 2020.03.01 |
---|---|
파이썬 숫자 자료형 (0) | 2020.03.01 |
[점프 투 파이썬] 04-3. 파일 읽고 쓰기 (0) | 2020.02.13 |
[점프 투 파이썬] 4장 연습문제 (0) | 2020.02.13 |