Life is too short, You need python
Python 정규표현식
정규 표현식의 기초, 메타 문자
. ^ $ * + ? { } [ ] \ | ( ) |
정규 표현식에서 위 메타 문자들이 사용되면 특별한 의미를 갖게 된다.
문자클래스 []
정규표현식이 [abc]라면 'a,b,c 중 한개의 문자와 매치'를 뜻한다.
[]안에서의 하이픈(-)을 사용하게 되면 두 문자 사이의 범위를 의미한다.
[a-c] = [abc], [0-5] = [012345]
[]내에서 ^ 메타 문자가 사용될 경우 반대(not)라는 의미를 갖는다.
정규표현식 | 설명 |
\d | 숫자와 매치 |
\D | 숫자가 아닌 것과 매치 |
\s | whitespace 문자와 매치, 맨 앞의 빈 칸은 공백문자를 의미한다. |
\S | whitespace 문자가 아닌 것과 매치 |
\w | 문자+숫자와 매치 |
\W | 문자+숫자가 아닌 문자와 매치 |
Dot(.)
정규 표현식의 dot메타 문자는 줄바꿈 문자인 \n을 제외한 모든 문자와 매치됨을 의미한다.
a.b = a와 b사이에 줄바꿈 문자를 제외한 어떤 문자가 들어가도 모두 매치
a.b=aab, a.b=a0b, a.b !=abc > 'abc'는 a문자와 b문자 사이에 어떤 문자라도 하나는 있어야 이 정규식과 일치하지 않으므로 매치되지 않음.
a[.]b > a와 b 사이에 Dot(.) 문자가 있으면 매치 >> a0b과는 매치가 안됨
반복(*)
ca*t : *문자 바로 앞에 있는 a가 0번 이상 반복되면 매치
ca*t=ct, ca*t=cat, ca*t=caaat
반복(+)
ca+t : +문자 바로 앞에 있는 a가 1번 이상 반복되면 매치
ca+t!=ct, ca+t=cat, ca+t=caaat
반복({m,n}, ?)
반복횟수가 m부터 n까지 인것을 매치할 수 있다,
1.{m}
ca{2}t : a가 2번 반복되면 매치
ca{2}t = caat, ca{2}t!=cat
2,{m,n}
ca{2,5} : a가 2~5번 반복되면 매치
3. ?
ca?t : a가 0~1번 사용되면 매치
파이썬에서 정규 표현식을 지원하는 re 모듈
import re
p=re.compile('ab*')
re.compile을 이용하여 정규 표현식을 컴파일한다.
정규식을 이용한 문자열 검색
메서드 | 목적 |
match() | 문자열 처음부터 정규식과 매치되는지 조사한다. |
search() | 문자열 전체를 검색하여 정규식과 매치되는지 조사한다. |
findall() | 정규식과 매치되는 모든 문자열을 리스트로 리턴한다. |
finditer() | 정규식과 매치되는 모든 문자열을 반복 가능한 객체로 리턴한다. |
match()
m=p.match("3python")
print(m)
>>>None
search()
m=p.search("python")
print(m)
>>><re.Match object; span=(0, 6), match='python'>
findall()
result=p.findall("life is too short")
print(result)
>>>['life', 'is', 'too', 'short']
finditer()
result=p.finditer("life is too short")
print(result)
>>><callable_iterator object at 0x000002109C215F70>
match 객체의 메서드
메서드 | 목적 |
group() | 매치된 문자열을 리턴한다. |
start() | 매치된 문자열의 시작 위치를 리턴한다. |
end() | 매치된 문자열의 끝 위치를 리턴한다. |
span() | 매치된 문자열의 (시작, 끝)에 해당되는 튜플을 리턴한다. |
p=re.compile('[a-z]+')
m=p.match("python")
print(m.group())
python
print(m.start())
0
print(m.end())
6
print(m.span())
(0, 6)
m=p.search("3 python")
print(m.group())
python
print(m.start())
2
print(m.end())
8
print(m.span())
(2, 8)
컴파일 옵션
옵션명 | 약어 | 설명 |
DOTALL | S | 줄바꿈 문자를 포함하여 모든 문자와 매치할 수 있도록 한다. |
IGNORECASE | I | 대 소문자에 관계 없이 매치할 수 있도록 한다. |
MULTILINE | M | 여러 줄과 매치할 수 있도록 한다. (^,$ 메타 문자의 사용과 관계가 있는 옵션이다) |
VERBOSE | X | verbose모드를 사용할 수 있도록 한다. (정규식을 보기 편하게 만들 수도 있고 주석 등을 사용할 수도 있다) |
DOTALL, S
메타 문자는 줄바꿈 문자를 제외한 모든 문자와 매치되는 규칙이 존재
p=re.compile('a.b',re.DOTALL)
m=p.match('a\nb')
print(m)
<re.Match object; span=(0, 3), match='a\nb'>
re.DOTALL은 \n에 상관없이 검색하고자 할 때 많이 사용한다.
|GNORECASE, |
re.I 옵션은 대 소문자 구분 없이 매치를 수행하고자 할 때 사용하는 옵션이다.
p=re.compile('[a-z]',re.I)
<re.Match object; span=(0, 3), match='a\nb'>
print(p.match('python'))
<re.Match object; span=(0, 1), match='p'>
print(p.match('Python'))
<re.Match object; span=(0, 1), match='P'>
print(p.match('PYTHON'))
<re.Match object; span=(0, 1), match='P'>
MULYILINE, M
^는 문자열 처음을 의미하고, $는 문자열의 마지막을 의미한다.
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이라는 문자열이 사용된 첫 번째 라인만 매치가 된 것이다.
p=re.compile("^python\s\w+",re.MULTILINE)
['python one', 'python two', 'python three']
re.MULTILINE을 넣어주면 각 라인의 처음을 리턴
VERBOSE, X
메타 문자
| : 메타 문자는 OR 과 동일한 의미로 사용 ex) a|b a또는 b
^ : 문자열의 맨 처음과 일치함을 의미한다.
$ : 문자열의 끝과 일치함을 의미한다.
\A : 문자열의 처음과 매치됨을 의미, ^와 동일한 의미이지만 re.MULTLINE옵션을 사용할 경우에는 다르게 해석된다. re.MULTLINE의 경우 라인별 문자열의 처음과 매치되지만 \A는 라인과 관계없이 전체 문자열의 처음하고만 매치된다.
\Z : 문자열의 끝과 매치됨을 의미한다. 이것역시 \A와 동일한 해석이된다.
\b : 단어 구분자이다. 보톤 단어는 whitespace에 구분이 된다.
\B : whitespace로 구분이 안된 단어의 경우 매치
그룹핑
ABC라는 문자열이 계속해서 반복되는지 조사하는 정규식의 경우 사용
group(인덱스) | 설명 |
group(0) | 매치된 전체 문자열 |
group(1) | 첫 번째 그룹에 해당되는 문자열 |
group(2) | 두 번째 그룹에 해당되는 문자열 |
group(n) | n 번째 그룹에 해당되는 문자열 |
p=re.compile('(ABC)+')
m=p.search('ABCABCABC OK?')
print(m)
print(m.group(0))
ABCABCABC
p=re.compile(r"\w+\s+\d+[-]\d+[-]\d+")
m=p.search("park 010-1234-1234")
park 010-1234-1234
p=re.compile(r"(\w+)\s+(\d+[-]\d+[-]\d+)")
m=p.search("park 010-1234-1234")
print(m.group(2))
010-1234-1234
그루핑된 문자열 재참조하기
p=re.compile(r'(\b\w+)\s+\1')
print(p.search('Paris in the the spring').group())
the the
그룹핑된 문자열에 이름 붙이기
그룸을 인덱스가 아닌 이름으로 참조할 수 있다면
p=re.compile(r"(?P<name>\w+)\s+((\d)+[-]\d+[-]\d+)")
m=p.search("park 010-1234-1234")
print(m.group("name"))
park
전방 탐색
p=re.compile(".+:")
m=p.search("http://google.com")
print(m.group())
http:
정규식 | 종류 | 설명 |
(?=...) | 긍정형 전방 탐색 | ...에 해당되는 정규식에 매치되어야 하며 조건이 통과되어도 문자열이 소모되지 않는다. |
(?!...) | 부정형 전방 탐색 | ...에 해당되는 정규식과 매치되지 않아야 하며 조건이 통과 되어도 문자열이 소모되지 않는다. |
문자열 바꾸기
p=re.compile('(blue|white|red)')
p.sub('colour','blue spcks and re shoes')