2023. 6. 20. 11:27ㆍ공부한 내용/점프 투 파이썬
1. 정규 표현식 살펴보기
1) 정규 표현식이란?
*정규 표현식(Regular Expressions)
-복잡한 문자열을 처리할 때 사용하는 기법
-파이썬만의 고유 문법이 아니라 문자열을 처리하는 모든 곳에서 사용
2) 메타 문자
*메타 문자(meta characters): 원래 그 문자가 가진 뜻이 아닌 특별한 용도로 사용하는 문자
*정규 표현식에서 사용하는 메타 문자: . ^ $ * + ? {} [] \ | ()
3) 문자 클래스 [ ]
*문자 클래스
-메타 문자: [ ]
-의미: [ ] 사이의 문자들과 매치
-[ ] 사이에는 어떤 문자도 들어갈 수 있음
(ex) [abc]: a, b, c 중 한 개의 문자와 매치
-a, b, c 중 하나라도 포함되어 있으면 매치
*[ ] 안의 두 문자 사이에 -를 사용하면 두 문자 사이의 범위를 의미
(ex) [a-zA-Z]: 알파벳 모두, [0-9]: 숫자
-단 문자 클래스 안에 ^ 메타 문자를 사용할 경우에는 반대(not)라는 의미를 가짐
(ex) [^0-9]: 숫자가 아닌 문자만 매치됨
4) Dot(.)
*줄바꿈 문자인 \n을 제외한 모든 문자와 매치됨을 의미하는 메타 문자
(ex) a.b: a와 b 라는 문자 사이에 줄바꿈 문자를 제외한 어떤 문자가 들어와도 모두 매치된다는 의미
※혼동하기 쉬운 예
*문자 클래스 [ ] 안에 Dot(.) 문자가 있는 경우
(ex) a[.]b: 이 때는 "모든 문자"라는 의미가 아닌 문자 "." 그대로를 의미
5) 반복(*)
*반복을 의미하는 * 메타 문자
*0번부터 무한대로 반복될 때 사용 (실제로는 메모리 제한으로 무한대가 아닌 2억 개 정도만 가능)
-* 바로 앞에 있는 문자가 0부터 무한대로 반복될 수 있음
(ex) ca*t: * 바로 앞에 있는 문자 a가 0부터 무한대로 반복될 수 있다는 의미
6) 반복(+)
*반복을 의미하는 + 메타 문자
*최소 1번 이상 반복될 때 사용
*0번부터 무한대로 반복될 때 사용하는 *와 차이를 보임
(ex) ca+t: + 바로 앞에 있는 문자 a가 1부터 무한대로 반복될 수 있다는 의미
7) 반복({m,n}, ?)
*{ } 메타 문자
-반복 횟수를 고정하는 의미
-{m, n} 정규식 사용 시 반복 횟수가 m부터 n까지 매치할 수 있음
-m 또는 n은 생략 가능 (생략된 m은 0과 동일, 생략된 n은 무한대(2억 개 미만)를 의미)
(ex) ca{2}t: { } 메타 문자 앞의 a가 반드시 2번 반복되어야만 매치
(ex2) ca{2, 5}t: { } 매타 문자 앞의 a가 2번~5번 반복되면 매치
*?
-{0,1}을 의미하는 메타 문자
(ex) ab?c: { } 메타 문자 앞의 b가 있어도 되고 없어도 된다는 의미
2. 정규 표현식 시작하기
1) re 모듈
*re(regular expression의 약어) 모듈
-파이썬이 정규 표현식을 지원하기 위해 제공하는 모듈
-파이선을 설치할 때 자동으로 설치되는 기본 라이브러리
*사용 방법
-re.compile
: 정규 표현식을 컴파일 -> 컴파일된 패턴(: 정규식을 컴파일한 결과) 객체 반환 -> 객체 p를 사용해 검색 수행
import re
p = re.compile("ab*") #ab가 0번 이상 나오는지 검사하고 싶은 경우
2) 문자열 검색 함수
import re
p = re.compile("[a-z]+") #a-z가 한번 이상 나오는지 검사하고 싶은 경우
(1) match(): 문자열의 처음부터 정규식과 매치되는지 조사
*문자열이 정규식에 부합하면 match 개체 반환
*문자열이 정규식에 부합하지 않으면 None 반환
#문자열이 정규식에 부합할 경우
m = p.match("python")
print(m)
#> <re.Match object; span=(0, 6), match="python"> #match 객체를 돌려줌
#문자열이 정규식에 부합하지 않는 경우
m = p.match("3 python")
print(m)
#> None
(2) search: 문자열 전체를 검색해 정규식과 매치되는지 조사
*정규식에 부합하는 부분을 match 객체로 반환
m = p.search("3 python")
print(m)
#> <re.Match object; span=(2, 8), match="3 python">
(3) findall(): 정규식과 매치되는 모든 문자열(substring)을 리스트로 돌려줌
result = p.findall("life is too short")
print(result)
#> ["life", "is", "too", "short"]
(4) finditer(): 정규식과 매치되는 모든 문자열(substring)을 반복 가능한 객체로 돌려줌
-반복 가능한 객체가 포함되는 각각의 요소는 match 객체
result = p.finditer("life is too short")
for r in result:
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, 17), match="short">
3) match 객체의 메서드
*match와 search 메서드를 수행한 결과로 반환되는 match 객체의 메서드 통해 아래 확인 가능
-매치된 문자열
-매치된 문자열의 시작 위치
-매치된 문자열의 끝 위치
메서드 | 목적 |
group() | 매치된 문자열을 돌려줌 |
start() | 매치된 문자열의 시작 위치를 돌려줌 |
end() | 매치된 문자열의 끝 위치를 돌려줌 |
span() | 매치된 문자열의 (시작, 끝)에 해당하는 튜플을 돌려줌 |
import re
p = re.compile("[a-z]+")
m = p.match("python")
m.group()
#> "python"
m.start()
#> 0 #결과로 반환되는 match 객체의 start() 결과값은 항상 0: match 메서드는 항상 문자열의 시작부터 조사하기 때문
m.end()
#> 6
m.span()
#> (0, 6)
import re
p = re.compile("[a-z]+")
m = p.search("python")
m.group()
#> "python"
m.start()
#> 2
m.end()
#> 8
m.span()
#> (2, 8)
4) 컴파일 옵션
*정규식을 컴파일 할 때 옵션 사용 가능
옵션 이름 | 약어 | 설명 |
DOTALL | S | dot 문자(.)가 줄바꿈 문자를 포함해 모든 문자와 매치 |
IGNORECASE | I | 대/소문자에 관계 없이 매치 |
MULTILINE | M | 여러 줄과 매치 (^, $ 메타 문자의 사용과 관계 있는 옵션) |
VERBOSE | X | verbose 모드 사용 (정규식을 보기 편하게 만들 수도 있고 주석 등 사용 가능) |
(1) DOTALL, S
*dot(.) 메타 문자는 줄바꿈 문자(\n)를 제외한 모든 문자와 매치되는 규칙이 있는데, 만약 \n 문자도 포함하여 매치하고 싶다면 re.DOTALL 혹은 re.S 사용
(2) IGNORECASE, I
*re.IGNORECASE 혹은 re.I 사용
(ex) [a-z] 정규식은 소문자만을 의미하지만 re.I 옵션으로 대/소문자 구별 없이 매치됨
(3) MULTILINE, M
*정규식을 여러 줄과 매치
*re.MULTILINE / re.M 사용
(ex) ^와 $ 사용
-^: 문자열의 처음
-$: 문자열의 마지막
-메타 문자를 문자열의 처음/마지막이 아닌 각 라인의 처음/마지막으로 적용하고 싶은 경우 re.MULTILINE, re.M 사용
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"]
(4) VERBOSE, X
*정규식을 주석 또는 줄 단위로 구분
-re.VERBOSE 혹은 re.X 사용
3. 정규 표현식 심화
1) 메타 문자
*+, *, [], {} 등의 메타 문자는 매치가 진행될 때 현재 매치되고 있는 문자열의 위치가 변경됨
*이와 달리 문자열을 소비시키지 않는 메타 문자도 존재
*문자열 소비가 없는(zero-width assertions) 메타 문자
2) | 메타 문자
*or과 동일한 의미
*A | B: A 또는 B라는 의미
p = re.compile("Crow|Servo")
m = p.match("CrowHello")
print(m)
#> <re.Match object; span=(0, 4), match="Crow">
3) ^메타 문자
*문자열의 맨 처음과 일치함을 의미
print(re.search("^Life", "Life is too short"))
#> <re.Match object; span-(0, 4), match="Life">
print(re.search("^Life", "My Life"))
#> None
4) $ 메타 문자
*^ 메타 문자와 반대의 경우
*문자열의 끝과 매치함을 의미
print(re.sesarch("short$", "Life is too short"))
#> <re.Match object; span=(12, 17), match="short">
print(re.sesarch("short$", "Life is too short, you need python"))
#> None
5) \A 메타 문자
*문자열의 처음곽 매치됨을 의미
*^ 메타 문자와 동일한 의미지만 re.MULTILINE 옵션 사용 시 다르게 해석됨
-^: 각 줄의 문자열의 처음과 매치
-\A: 줄과 상관없이 전체 문자열의 처음하고만 매치
6) \Z 메타 문자
*문자열의 끝과 매치됨을 의미
*\A와 동일하게 re.MULTILINE 옵션을 사용할 경우 $ 메타 문자와 다르게 해석됨
-$: 각 줄의 문자열의 끝과 매치
-\Z: 줄과 상관없이 전체 문자열의 끝하고만 매치
7) \b 메타 문자
*단어 구분자(Word boundary), 보통 단어는 whitespace에 의해 구분됨
p = re.compile("r\bclass\b") #\bclass\b: 앞뒤가 whitespace로 구분된 class라는 단어와 매치
print(p.search("no class at all"))
#> <re.Match object; span=(3, 8), match="class">
-파이썬 규칙에 의하면 \b는 백스페이스(BackSpace)를 의미하므로, 정규식에서 사용할 때는 백스페이스가 아닌 단어 구분자임을 알리기 위해 raw string임을 알려주는 기호 r을 반드시 붙여야 함
8) \B 메타 문자
*\b 메타 문자와 반대의 경우
*whitespace로 구분된 단어가 아닌 경우에만 매치
p = re.compile(r"\Bclass\B")
print(p.search("no class at all"))
#> None
print(p.search("the declassified algorithm"))
#> <re.Match object; span=(6, 11), match="class">
print(p.search("one subclass is"))
#> None
'공부한 내용 > 점프 투 파이썬' 카테고리의 다른 글
[파이썬] 점프 투 파이썬 - 라이브러리 (0) | 2023.06.17 |
---|---|
[파이썬] 점프 투 파이썬 - 예외 처리와 내장 함수 (0) | 2023.06.15 |
[파이썬] 점프 투 파이썬 - 모듈과 패키지 (0) | 2023.06.15 |
[파이썬] 점프 투 파이썬 - 클래스 (0) | 2021.07.04 |
[파이썬] 점프 투 파이썬 - 함수, 파일 입출력 (0) | 2021.07.01 |