Python Regular Expression
Python Regular Expression
정규식 기반으로 탐색을 진행할 수 있어, crawling, pattern matching 유형의 문제를 효과적으로 풀이할 수 있다.
메타 문자
정규식에서 특정 의미를 나타내는 기호를 의미하는 것으로 특정 패턴을 나타내고자 할 때 메타 문자를 활용한다.
자주 사용되는 기호
symbol | definition | synonym |
---|---|---|
[^] | not의 의미로, 해당 문자들은 사용되지 않는다. | |
^[] | 특정 문자 클래스로 시작하는 문자열을 파싱함 | |
[]$ | 특정 문자 클래스로 끝나는 문자열을 파싱함 | |
\d | 0~9 까지의 모든 숫자를 의미 | [0-9] |
\d | 0~9 까지의 모든 숫자를 의미 | [0-9] |
\d | 0~9 까지의 모든 숫자를 의미 | [0-9] |
\D | 숫자를 제외한 나머지 문자 | [^0-9] |
\s | whitespace에 대응되는 문자를 의미 | [ \t\n\r\f\v] |
\S | whitespace가 아닌 모든 문자 | [^ \t\n\r\f\v] |
\w | 숫자와 알파벳의 조합을 나타낸다. | [0-9a-zA-Z] |
\W | 숫자, 알파벳을 제외한 모든 문자 | [^0-9a-zA-Z] |
알파벳, 숫자, 공백의 경우 많이 쓰이는 문자 클래스로 특정 기호로 나타낼 수 있다.
문자 클래스
사용될 수 있는 문자의 조합을 나타내기 위해 []을 이용하여 제한한다.
[0-9 ]: 숫자와 공백이 올 수 있다
[a-g]: a~g 까지의 문자가 올 수 있다.
Dot ‘\n’을 제외한 모든 문자
a.b ==> a0b,acb,a3b ... 등이 해당된다.
.을 표현하기 위해서는 [.]을 활용해야한다.
반복
특정 문자 클래스에 대한 반복이 있는 경우, *,+를 활용하여 반복을 표현할 수 있다.
*은 0개 이상의 문자가 반복됨을 의미한다. +은 1개 이상의 문자가 반복됨을 의미한다. {m,n}은 m개 이상, n개 이하의 문자가 반복됨을 의미한다.
*은 {0,}, +은 {1,}로 나타낼 수 있다.
ab*c ==> ac, abc, abbc ...
ab+c ==> abc, abbc, abbbc ...
ab{2,5}c ==> abbc, abbbc, abbbbc ...
선택
?은 특정 문자가 올 수 있음을 의미한다.
ab?c ==> abc, ac
정규표현식 예시
- 전화번호
(\d{3})-(\d{4})-(\d{4})
()을 사용하였는데, 이는 그룹을 묶는 기준을 정의하는 것이다. 위와 같이 표현하면 총 3개의 그룹으로 표현된다.
- 이메일
([a-zA-Z0-9_\-.]+)@([a-zA-Z0-9_\-]+)\.([a-zA-Z0-9_\-]+)
이메일의 경우 계정@도메인@최상위도메인 형태로 나타낼 수 있다.
re 모듈 함수
python re 모듈에서 제공해주는 함수를 활용하여 문자열 내부에 정규식을 통한 검색을 쉽게 할 수 있다.
match
특정 문자열의 처음부터 정규식과 매칭되는 지 확인한다.
import re
pattern=re.compile('[0-9]+')
print(pattern.match("python3"))
==> None
print(pattern.match("3697 python3"))
==> <re.Match object; span=(0, 4), match='3697'>
search
match 와 유사하지만, 특정 문자열의 중간에서부터 매칭되어도 문자열을 패턴을 추출할 수 있다.
import re
pattern=re.compile('[0-9]+')
print(pattern.match("python3"))
==> <re.Match object; span=(6, 7), match='3'>
print(pattern.match("3697 python3"))
==> <re.Match object; span=(0, 4), match='3697'>
findall
매칭되는 모든 pattern에 대한 추출을 수행한다.
import re
pattern=re.compile('[0-9]+')
print(pattern.findall("3697 python3"))
==> ['3697', '3']
finditer
findall 과 유사하지만, match 객체 리스트로 반환한다.
print(pattern.findall("3697 python3"))
==> <callable_iterator object at 0x000002AA859DE080>
matchings=pattern.finditer("3697 python3")
for matching in matchings:
print(matching)
<re.Match object; span=(0, 4), match='3697'>
<re.Match object; span=(11, 12), match='3'>
match 객체에서 제공하는 함수
function | description |
---|---|
group | 매치된 문자열 반환 |
start | 문자열의 시작 위치 반환 |
end | 문자열의 끝 위치 반환 |
span | 문자열의 시작, 끝 위치를 튜플 형태로 반환 |
groups | 문자열 내부에 그룹이 있는 경우 그룹들을 리스트 형태로 반환 |
>>> matching=pattern.match("3697 python3")
>>> matching.group()
'3697'
>>> matching.start()
0
>>> matching.end()
4
>>> matching.span()
(0, 4)
#groups()
>>> pattern=re.compile("(\d{3})-(\d{4})-(\d{4})")
>>> pattern.match("010-1234-5678")
<re.Match object; span=(0, 13), match='010-1234-5678'>
>>> matching=pattern.match("010-1234-5678")
>>> matching.group()
'010-1234-5678'
>>> matching.groups()
('010', '1234', '5678')
댓글남기기