아래 내용중에 ###표시는 """ (따옴표3개)로 바꿔야 한다.
1. 대괄호 ([])
[] 사이의 문자들과 매치하는지 검사
[abc]
a = a일치
before = b일치
dude = 불일치
하이픈(-)을 이용해서 표현 가능
[a-c] = [abc]
[0-5] = [012345]
2. Dot(.)
줄바꿈 문자 (\n)를 제외한 모든 문자와 매치 되는지 검사
a.b
"aab" = 가운데 a가 모든 문자와 일치
"a0b" = 가운데 문자"0"이 모든 문자와 일치
"abc" = a와 b 문자 사이에 어떤 문자라도 하나는 있어야 하는데, 없으므로 불일치
3. 반복 (*)
0번 이상 반복 되어야 일치
ca*t
"ct" = a가 0번 반복하므로 일치
"cat" = a가 0번 이상(1번) 반복하므로 일치
"caaat" = a가 0번 이상(3번) 반복하므로 일치
4. 반복 (+)
1번 이상 반복 되어야 일치
ca*t
"ct" = a가 0번 반복하므로 불일치
"cat" = a가 0번 이상(1번) 반복하므로 일치
"caaat" = a가 0번 이상(3번) 반복하므로 일치
5. 반복 ({m,n}, ?)
ca{2}t : a가 딱 2번만 반복되어야 일치
"cat" = a가 1번만 반복되어 불일치
"caat" = a가 2번 반복되어 일치
ca{2,5}t : a가 2번 이상 5번 이하로 반복되면 일치
"cat" = a가 1번만 반복되어 불일치
"caat" = a가 2번 반복되어 일치
"caaaaat" = a가 5번 반복되어 일치
ab?c
? : 0 또는 1과 같은 표현 = b가 없거나 1번만 있거나 하면 일치
"abc" = "b"가 1번 있어서 일치
"ac" = b가 0번 사용되어 일치
정규 표현식 시작하기
re모듈 필요
import re
6. 정규 표현식 지정 = 패턴객체 생성
p = re.compile('ab*') #p는 패턴객체
패턴객체 이용하기 4가지
match, search, findall, finditer
7. match
import re
p = re.compile('[a-z]+')
m = p.match("python")
print(m) #<re.Match object; span=(0, 6), match='python'> #매치
n = p.match("3 python")
print(n) #None #매치안됨
8. search
import re
p = re.compile('[a-z]+')
m = p.search("python")
print(m) #<re.Match object; span=(0, 6), match='python'> #매치
n = p.search("3 python")
print(n) #<re.Match object; span=(2, 8), match='python'> #매치
9. findall
import re
p = re.compile('[a-z]+')
m = p.findall("life is too shot")
print(m) #['life', 'is', 'too', 'shot'] #매치되는 문자를 리스트에 담는다. 구분은 공백 기준.
10. finditer
import re
p = re.compile('[a-z]+')
m = p.finditer("life is too shot") #<callable_iterator object at 0x00000034971BAB88>
print(m)
for r in m:
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, 16), match='shot'>
11. * match객체의 메서드 1
group(), start(), end(), span()
group() = 매치된 문자열을 리턴
start() = 매치된 문자열의 시작 위치를 리턴
end() = 매치된 문자열의 끝 위치를 리턴
span() = 매치된 문자열의 시작, 끝에 해당되는 튜플을 리턴
import re
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)
12. 컴파일 옵션 : DOTALL, S
원래 Dot(.)은 줄바꿈('\n')을 제외한 모든 문자를 의미한다.
DOTALL = 줄바꿈 문자도 포함하도록 하는 옵션이다. (줄바꿈 포함 모든 문자)
S = 약어로 사용 가능
import re
p = re.compile('a.b')
m = p.match("a\nb")
print(m) #None
#p = re.compile('a.b', re.DOTALL)
p = re.compile('a.b', re.S)
m = p.match("a\nb")
print(m) #<re.Match object; span=(0, 3), match='a\nb'>
p = re.compile('a.b', re.S)
m = p.match("a\nb")
print(m) #<re.Match object; span=(0, 3), match='a\nb'>
12. 컴파일 옵션 : IGNORECASE, I
대소문자를 구분하지 않고 매치한다.
import re
p = re.compile('[a-z]')
print(p.match('python')) #<re.Match object; span=(0, 1), match='p'>
print(p.match('Python')) #None
print(p.match('PYTHON')) #None
#p = re.compile('[a-z]', re.IGNORECASE)
p = re.compile('[a-z]', re.I)
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'>
13. MULTILINE, M
여러줄을 인식할 수 있게 해주는 옵션 (이 옵션이 없으면 기본 1줄만 검사)
각 라인별로 새로운 줄이라고 인식함.
import re
p = re.compile("^python\s\w+")
#^:맨처음, ^python : 맨처음 python으로 시작, \s : 공백, \w : 알파벳,숫자,_중의 한 문자, + : 앞에 글자가 1번 이상 반복하면 매치
data = ####python one
life is too short
python two
you need python
python three###
print(p.findall(data)) #['python one']
#p = re.compile("^python\s\w+", re.MULTILINE)
p = re.compile("^python\s\w+", re.M)
#^:맨처음, ^python : 맨처음 python으로 시작, \s : 공백, \w : 알파벳,숫자,_중의 한 문자, + : 앞에 글자가 1번 이상 반복하면 매치
data = ###python one
life is too short
python two
you need python
python three###
print(p.findall(data)) #['python one', 'python two', 'python three']
14. VERBOSE, X
원래는 긴 정규표현식을 줄바꿈해서 작성하면 컴파일이 안되는데
VERBOSE 옵션을 주게되면 줄바꿈 해서 정규표현식을 작성하더라도 오류가 발생하지 않는다.
긴 정규표현식을 하나씩 뜯어서 줄바꿈으로 구분하고 주석을 달아놓을 때 유용하게 사용된다.
import re
charref = re.compile(r'&[#](0[0-7]+|[0-9]+|x[0-9a-fA-F]+);')
charref = re.compile(r###
&[#] #Start of a numeric entity reference
(
0[0-7]+ #Octal form
|[0-9]+ #Decimal form
|x[0-9a-fA-F]+ #Hexadecimal form
)
; #Trailing semicolon
###, re.VERBOSE)
15. 백슬래시 문제
예) \section 같은 문자를 찾을 때 \s는 정규표현식에서 공백문자로 인식한다.
\d : 숫자와 매치 = [0-9]와 동일
\D : 숫자가 아닌 것과 매치 = [^0-9]와 동일
\s : 공백을 표현하는 문자와 매치 = [\t\n\r\f\v]와 동일
\S : 공백 문자가 아닌 것과 매치 = [^\t\n\r\f\v]와 동일
\w : 문자+숫자와 매치, [a-zA-Z0-9_]와 동일
\W : 문자+숫자가 아닌 문자와 매치, [^a-zA-Z0-9_]와 동일
이런 옵션들과 문자를 구분하기 위해서 \(백슬래시) 문자를 나타낼땐 \\ (백슬래시를 2번) 적어준다.
백슬래시 문자2개를 연속해서 인식하려면 백슬래시를 4개 넣어줘야 한다ㅣ \\\\
그런데 이렇게 하면 너무 번거로우니깐 r'\\문자열' 이렇게 하면 백슬래시 문자 2개로 인식한다.
(r = rawstring)
p = re.compile("\\\\section")
p = re.compile(r"\\section")
16. 메타문자 | (OR)
A|B : 앞에꺼(A) 또는 뒤에꺼(B)와 매치되면~
import re
p = re.compile('Crow|Servo')
m = p.match('CrowHello')
print(m) #<re.Match object; span=(0, 4), match='Crow'>
17. 메타문자 ^
맨처음, 문자열의 맨 앞부분을 의미
import re
print(re.search('^Life','Life is too short')) #<re.Match object; span=(0, 4), match='Life'>
print(re.search('^Life','My Life')) #None
18. 메타문자 $
맨끝, 문자열의 맨 끝부분을 의미
문자열$ : 문자열이 문장에 맨 끝에 있는지?
import re
print(re.search('short$','Life is too short')) #<re.Match object; span=(12, 17), match='short'>
print(re.search('short$','Life is too short, you need python')) #None
19. 메타문자 \b (공백을 나타내는 문자)
import re
p = re.compile(r'\bclass\b') #'(공백)class(공백)'을 의미
print(p.search('no class at all')) #<re.Match object; span=(3, 8), match='class'>
print(p.search('the declassfied algorithm')) #None
print(p.search('one subclass is')) #None
.. 메타문자는 구글 검색으로 찾아서 보라
20. 그루핑 ()
표현식을 묶어주는 역할
ABC+ : C만 반복되는 것을 찾는다면 = ABCCCCC
(ABC)+ : ABC가 반복되는 것을 찾는다는 의미 = ABCABCABC
import re
p = re.compile('(ABC)+')
m = p.search('ABCABCABC OK?')
print(m) #<re.Match object; span=(0, 9), match='ABCABCABC'>
print(m.group()) #ABCABCABC
그룹핑을 해놓게되면 매칭객체에서 따로 불어올수도 있다.
import re
p = re.compile(r"(\w+)\s+\d+[-]\d+([-]\d+)")
m = p.search("park 010-1234-1234")
print(m.group()) #park 010-1234-1234
print(m.group(0)) #park 010-1234-1234
print(m.group(1)) #park #첫번째 그루핑() 문자열
print(m.group(2)) #-1234 #두번째 그루핑() 문자열
그루핑 된 게 있을 때 \1을 써주면 그루핑 되었던 걸 한번 더 써준다는 의미
import re
p = re.compile(r"(\b\w+)\s+\1")
m = p.search("Paris in the the spring")
print(m.group()) #the the
그루핑된 문자열에 이름 붙이기 ?P<name>
이름을 붙여 그루핑된 문자열을 가져올 수도 있다.
그루핑된 게 많을 때는 숫자로 불러오기 보다 지정된 이름으로 불러오면 읽기 편하다.
import re
p = re.compile(r"(?P<name>\w+)\s+((\d+)[-]\d+[-]\d+)")
m = p.search("Park 010-1234-1234")
print(m.group("name")) #Park
이름이 붙여진 그루핑을 뒤쪽에서 불러올수도 있다. (/1과 같으나 이름으로 불러온다는 게 다름)
import re
p = re.compile(r"(?P<word>\b\w+)\s+(?P=word)")
m = p.search("Paris in the the spring")
print(m.group()) #the the
print(m.group("word")) #the
전방탐색 : 긍정형
(?=문자)
'?='다음에 오는 '문자'가 검색 조건에는 포함되나 결과에는 포함되지 않는다.
import re
p = re.compile(".+:")
m = p.search("http://google.com")
print(m.group()) #http:
p = re.compile(".+(?=:)")
m = p.search("http://google.com")
print(m.group()) #http
전방탐색 : 부정형
(?!문자)
'?!'다음에 오는 '문자'는 포함되지 않게 해달라는 의미
import re
p = re.compile(".*[.](?!bat$).*$", re.M)
l = p.findall(###
autoexec.exe
autoexec.bat
autoexec.jpg
###)
print(l) #['autoexec.exe', 'autoexec.jpg']
import re
p = re.compile(".*[.](?!bat$|exe$).*$", re.M) # | = OR = 또는..
l = p.findall(###
autoexec.exe
autoexec.bat
autoexec.jpg
###)
print(l) #['autoexec.jpg']
문자열 바꾸기 : sub
import re
p = re.compile('(blue|white|red)')
r = p.sub('colour', 'blue socks and red shoes')
print(r) #colour socks and colour shoes
Greedy(탐욕스러운 뜻) vs Non-Greedy
Greedy : <.*> # < 문자로 시작해서 최대한 뒤쪽의 > 문자까지 포함
Non-Greedy : <.*?> # < 문자로 시작해서 바로 다음 > 문자가 나올때 까지만.
import re
s = '<html><head><title>Title</title>'
print(re.match('<.*>', s).group()) #<html><head><title>Title</title>
print(re.match('<.*?>', s).group()) #<html>
https://www.youtube.com/watch?v=dTDoTR0MXjU
[파이썬] PyAutoGUI 라이브러리로 키보드, 마우스 제어하기 (정리중) (0) | 2020.11.18 |
---|---|
[파이썬] 소스코드.py 파일을 exe 실행 파일로 만들기 (pyinstaller) 메모 (0) | 2020.10.27 |
[파이썬] BeautifulSoup 웹크롤링 하다가 메모... (0) | 2020.08.26 |
[파이썬] argv[], *args, **kwargs 메모 (0) | 2020.08.26 |
[파이썬] 전자공시(Open DART) 재무제표 크롤링 (스크랩) (2) | 2020.08.25 |