1. 정규표현식이란
Regular Expression (또는 Regex)
특정한 규칙을 가진 문자열의 집합을 표현하는 데 사용하는 형식 언어. (Wikipedia)
2. 정규표현식의 구조
/PATTERN/FLAG
/
:- 정규표현식임을 알리는 기호.
- 정규표현식의 시작과 끝에 위치함.
PATTERN
- 정규표현식으로 찾고자하는 문자열의 패턴
FLAG
- 옵션
3. 정규표현식, 표현의 종류
3.1. 그룹과 범위 group and ranges
|
- OR, 또는
()
- 그룹 지정
- 복수의 패턴을 하나의 그룹으로 묶어 찾는 식으로 사용할 수 있음
- 예시)
- gray 또는 grey 를 찾고자 할 때
/gr(a|e)y/gm
- URL 패턴을 찾고자 할 때
/(http|https):// ... 이하 생략
- 한번에 패턴을 검색하되, 다른 별개의 그룹으로 찾고자 할 때
(Hi|Hello)|(AND)
- 그룹을 지정하고 싶지 않을 때
- gray 또는 grey 를 찾고자 할 때
(?:)
- 그룹을 지정하지 않음
- 예시)
- grey 또는 gray를 찾되, 그룹으로 지정하지않음
(?:grey|gray)
- grey 또는 gray를 찾되, 그룹으로 지정하지않음
[]
- 대괄호의 모든 문자열에 대해서, 하나라도 만족하는 문자열
- 예시)
- gr로 시작하는 모든 알파벳 3개로 구성된 문자열
gr[a-zA-Z0-9]
- gr과 y사이에 a, e, d 중 하나를 충족하는 문자열
gr[aed]y
- gr로 시작하는 모든 알파벳 3개로 구성된 문자열
[^]
- 부정 문자열. 괄호 안의 어떤 문자열을 제외한 문자열
- 예시)
- 대소문자 알파벳, 숫자, 공백이 아닌 모든 문자열
[^a-zA-Z0-9 ]
- 대소문자 알파벳, 숫자, 공백이 아닌 모든 문자열
3.2. 수량 quantifier
?
- 없거나, 있거나 (zero or one)
*
- 없거나, 있거나, 많거나 (zero or more)
+
- 하나 또는 많이 (one or more)
{n}
- n번 반복
{n,}
- 최소 n번 반복
{,m}
- 최대 m번 반복
{n, m}
- 최소 n번, 최대 m번 반복
3.3. 경계 boundary-type
\b
- 단어의 경계
- 문자열의 앞 또는 뒤에서 쓰이는 문자열만 찾음
\B
- 단어의 경계가 아님
^
- 문장의 시작
$
- 문장의 끝
3.4. 문자열 character classes
\
- 특수 문자가 아닌 문자
- 예시)
- 정규표현의
.
이 아닌 실제 문장에서.
을 찾고자 할 때\.
- 정규표현식에서 그룹지정의
()
가 아닌, 실제 텍스트에서 ()를 찾고자 할 때,\(\)
- 정규표현의
.
- 줄바꿈을 제외한 모든 문자
\d
- 숫자
\D
- 숫자 아님
\w
- 문자열
\W
- 문자열 아님
\s
- 공백
\S
- 공백 아님
4. 간단한 예제
4.1. 전화번호 찾기
\d{2,3}[- .]\d{3,4}[- .]\d{4}
4.2. E-mail 찾기
[\S]+@[a-zA-Z0-9-]+\.[a-z.]+
4.3. URL 찾기
(Youtube 주소에서 default url을 제외한 영상 고유의 id찾기)
(https?:\/\/)?(www\.)?youtu\.be\/([a-zA-Z0-9-]+)
5. 파이썬과 정규표현식
5.1. 정규표현식 패키지 - re
- 파이썬에 내장된
re
패키지를 사용하면 됨. (문서)
import re
5.2. 주요 기능
5.2.1. 정규식 패턴 정의
re.compile
- 정규식 패턴을 직접 변수로 전달할 수도 있겠지만,
re.compile
을 통해 미리 컴파일하여 객체로 사용하는 것이 편함
- 정규식 패턴을 직접 변수로 전달할 수도 있겠지만,
pat = re.compile('[a-z]+')
print(pat)
re.compile('[a-z]+')
5.2.2. 검색
.match
- 문자열의 처음부터 정규식 패턴과 일치하는지 검색
- 묹자열의 처음부터 일치하지 않을 경우 검색되지 않음
m = re.match(pat, "python @789")
print(m)
<re.Match object; span=(0, 6), match='python'>
m = re.match(pat, "#123 python @789")
print(m)
None
.search
- 문자열 전체에 대해서 정규식 패턴과 일치하는 문자열 검색
m = re.search(pat, "#123 python @789")
print(m)
<re.Match object; span=(5, 11), match='python'>
re.findall
- 정규식 패턴과 매치되는 모든 부분 문자열(substring)을 리스트로 리턴
m = re.findall(pat, "#123 python @789")
print(m)
['python']
re.finditer
- 정규식 패턴과 매치되는 모든 부분 문자열을 iter 객체로 리턴
m = re.finditer(pat, "#123 python pythonista, python @789")
for match in m:
print(match)
<re.Match object; span=(5, 11), match='python'>
<re.Match object; span=(12, 22), match='pythonista'>
<re.Match object; span=(24, 30), match='python'>
- 검색 객체의 메서드
.group()
: 매치된 문자열 리턴.start()
: 매치된 문자열의 시작 위치 리턴.end()
: 매치된 문자열의 끝 위치 리턴.span()
: 매치된 문자열의 (시작, 끝) 튜플 리턴
m = re.finditer(pat, "#123 python pythonista, python @789")
for match in m:
print("매치된 문자열 match : {}".format(match.group()))
print("매치된 문자열 start : {}".format(match.start()))
print("매치된 문자열 end : {}".format(match.end()))
print("매치된 문자열 span : {}".format(match.span()))
print("----------------------------")
매치된 문자열 match : python
매치된 문자열 start : 5
매치된 문자열 end : 11
매치된 문자열 span : (5, 11)
----------------------------
매치된 문자열 match : pythonista
매치된 문자열 start : 12
매치된 문자열 end : 22
매치된 문자열 span : (12, 22)
----------------------------
매치된 문자열 match : python
매치된 문자열 start : 24
매치된 문자열 end : 30
매치된 문자열 span : (24, 30)
----------------------------
5.3. 문자열 변경
re.sub(정규식패턴, 변경할문자열, 타겟문자열)
- 문자열 바꾸기
- 파이썬에서
.replace()
와 같은 역할을 함
m = re.sub(pat, "hello", "#123 python @789")
print(m)
#123 hello @789