점프 투 파이썬 DAY17(정규 표현식 시작하기)

정지범·5일 전

점프 투 파이썬

목록 보기
34/37

08-2 정규 표현식 시작하기

목차

  • 1. 메타 문자란?
  • 2. 문자 클래스 [ ]
  • 3. 자주 사용하는 문자 클래스 \d, \s, \w
  • 4. Dot .
  • 5. 반복 *, +, {}, ?
  • 6. 파이썬 re 모듈
  • 7. match()와 search()
  • 8. findall()과 finditer()
  • 9. Match 객체
  • 10. 정규식 컴파일 옵션
  • 11. 역슬래시와 Raw String

1. 메타 문자란?

정규 표현식에서는 일반적인 문자 외에도 특별한 의미를 가진 문자를 사용한다.

이러한 문자를 메타 문자(Meta Character) 라고 한다.

대표적인 메타 문자는 다음과 같다.

. ^ $ * + ? { } [ ] \ | ( )

예를 들어 일반 문자열에서

*

은 단순한 별표 문자이지만 정규식에서는

앞의 문자가 0번 이상 반복

이라는 특별한 의미를 가진다.

따라서 정규식을 공부할 때는

각 메타 문자가 어떤 규칙을 표현하는지 이해하는 것이 핵심이다.


2. 매치(Match)란?

정규식에서는 매치된다라는 표현을 많이 사용한다.

매치란

문자열이 정규식에서 지정한 패턴과 일치한다

라는 의미이다.

예를 들어 정규식이

abc

이고 문자열도

abc

라면

정규식 : abc
문자열 : abc

→ Match O

라고 할 수 있다.


3. 문자 클래스 [ ]

가장 먼저 알아볼 메타 문자는

[ ]

이다.

[]는

대괄호 안에 있는 문자 중 하나

와 매치한다.

예를 들어

[abc]

는

a 또는 b 또는 c

중 하나를 의미한다.


[abc] 예제

정규식 : [abc]

문자열을 비교해 보자.

"a"
→ a가 존재
→ Match O

"banana"
→ b 또는 a가 존재
→ Match O

"dog"
→ a, b, c가 없음
→ Match X

여기서 중요한 점은

[abc]

가 문자열 "abc" 전체를 의미하는 것이 아니라는 것이다.

[abc]

= a 또는 b 또는 c 중 한 문자

이다.


4. [ ]에서 범위 지정하기

문자를 하나씩 모두 적어야 한다면 불편할 수 있다.

예를 들어 모든 숫자를 표현하려면

[0123456789]

라고 작성할 수도 있지만 다음처럼 간단하게 표현할 수 있다.

[0-9]

-를 사용하면 범위를 지정할 수 있다.


문자 범위

[a-z]
a부터 z까지의 소문자
[A-Z]
A부터 Z까지의 대문자
[0-9]
0부터 9까지의 숫자

대소문자 모두 표현하기

[a-zA-Z]

는

영문 소문자 또는 영문 대문자

를 의미한다.


한글 범위

한글 문자를 대상으로 다음과 같은 패턴도 볼 수 있다.

[가-힣]

즉 한글 음절 범위를 표현할 때 사용할 수 있다.


5. 문자 클래스 안의 ^

문자 클래스 []의 맨 앞에서 ^를 사용하면 의미가 반대가 된다.

[^0-9]

는

숫자가 아닌 문자

를 의미한다.

즉

[0-9]
→ 숫자

[^0-9]
→ 숫자가 아닌 것

이다.


예제

[^abc]

는

a, b, c가 아닌 문자

를 의미한다.

[^A-Z]

는

영문 대문자가 아닌 문자

를 의미한다.


6. 자주 사용하는 문자 클래스

정규식에서는 자주 사용하는 패턴을 더 짧게 표현할 수 있다.

정규식의미
\d숫자
\D숫자가 아닌 문자
\s공백 계열 문자
\S공백 계열이 아닌 문자
\w단어를 구성하는 문자
\W단어를 구성하는 문자가 아닌 것

대문자로 바뀌면 대부분 반대 의미라고 생각하면 이해하기 쉽다.


7. \d

\d는 숫자를 의미한다.

\d

일반적으로 숫자 한 글자를 찾는 데 사용할 수 있다.

예를 들어

import re

p = re.compile(r"\d")

print(p.findall("abc123"))

결과

['1', '2', '3']

이다.


여러 숫자를 한 번에 찾으려면?

현재

\d

는 숫자 한 글자씩 찾는다.

숫자가 여러 개 연속된 부분을 찾고 싶다면 뒤에서 배우는 +를 붙인다.

\d+

예를 들어

import re

p = re.compile(r"\d+")

print(p.findall("age=25 score=100"))

결과

['25', '100']

이다.


8. \D

대문자인

\D

는 \d의 반대이다.

즉

숫자가 아닌 문자

를 의미한다.

\d  → 숫자
\D  → 숫자가 아닌 것

9. \s

\s

는 Whitespace 문자와 매치한다.

대표적으로

공백
탭
줄바꿈

등이 포함된다.

예를 들어

import re

p = re.compile(r"\s")

print(p.findall("hello python"))

문자열 중간의 공백이 매치된다.


10. \S

\S

는 \s의 반대이다.

즉

공백 문자가 아닌 것

을 의미한다.


11. \w

\w

는 일반적으로 단어를 구성하는 문자를 찾을 때 사용한다.

예를 들어

import re

p = re.compile(r"\w+")

print(p.findall("python_2026"))

결과

['python_2026']

처럼 사용할 수 있다.

Python 3의 re에서는 기본적으로 유니코드를 사용하기 때문에 \w가 영문자와 숫자뿐 아니라 한글과 같은 유니코드 문자에도 매치될 수 있다.


12. \W

\W

는 \w의 반대이다.

즉

단어를 구성하지 않는 문자

를 의미한다.

예를 들면 공백이나 일부 특수문자를 찾는 데 활용할 수 있다.


13. . Dot 메타 문자

정규식에서

.

은

줄바꿈 \n을 제외한 거의 모든 문자 한 개

를 의미한다.

예를 들어

a.b

라는 정규식이 있다고 해보자.

구조는

a
+
아무 문자 1개
+
b

이다.


예제

aab
a + a + b

→ Match O
a7b
a + 7 + b

→ Match O
a-b
a + - + b

→ Match O

하지만

ab

는 중간에 문자가 없으므로 매치되지 않는다.


14. . 자체를 찾고 싶다면?

다음 두 정규식은 의미가 다르다.

a.b
a + 아무 문자 + b

반면

a[.]b

는

a + 실제 점(.) + b

를 의미한다.

따라서

a.b

문자열 자체를 찾을 때 사용할 수 있다.


15. 반복 메타 문자 *

*

는

바로 앞의 문자가 0번 이상 반복

된다는 의미이다.

예를 들어

ca*t

를 살펴보자.

여기서 *는 바로 앞의 a에 적용된다.

c
+
a가 0번 이상
+
t

라는 의미이다.


매치 예제

문자열결과이유
ctOa가 0번
catOa가 1번
caatOa가 2번
caaaaatOa가 여러 번

가장 중요한 부분은

0번도 가능

하다는 것이다.

따라서

ct

도 매치된다.


16. 반복 메타 문자 +

+

는

바로 앞의 문자가 1번 이상 반복

된다는 의미이다.

예를 들어

ca+t

는

c
+
a가 1번 이상
+
t

이다.


*와 비교

정규식ctcatcaaat
ca*tOOO
ca+tXOO

차이는

*

0번 이상
+

1번 이상

이다.

이 차이를 꼭 기억하자.


17. {m}

반복 횟수를 정확하게 지정하고 싶을 때

{}

를 사용할 수 있다.

예를 들어

a{3}

은

a가 정확히 3번

이라는 의미이다.


예제

ca{2}t

는

c
+
a 두 번
+
t

이므로

caat

과 매치된다.

하지만

cat

은 a가 한 번이므로 매치되지 않는다.


18. {m,n}

반복 횟수의 범위를 지정할 수도 있다.

{m,n}

은

최소 m번
~
최대 n번

이라는 의미이다.

예를 들어

a{2,4}

는

aa
aaa
aaaa

처럼 a가 2~4번 반복되는 경우를 의미한다.


한쪽을 생략할 수도 있다

a{3,}
a가 3번 이상
a{,3}
a가 3번 이하

라고 이해할 수 있다.


19. ?

?

는

바로 앞의 문자가 0번 또는 1번

나타난다는 의미이다.

즉

있어도 되고
없어도 된다

라고 생각하면 쉽다.

예를 들어

colou?r

에서 u?는

u가 없어도 되고
u가 한 번 있어도 됨

이라는 의미이다.

따라서

color

와

colour

둘 다 매치할 수 있다.


20. 반복 메타 문자 한 번에 정리

메타 문자의미
*0번 이상
+1번 이상
?0번 또는 1번
{m}정확히 m번
{m,n}m~n번
{m,}m번 이상
{,n}n번 이하

특히

*
+
?

세 개를 많이 사용한다.


21. *, +, ? 관계

다음처럼 생각할 수도 있다.

*

{0,}
+

{1,}
?

{0,1}

즉 간단하게 자주 사용하는 반복 표현을

*
+
?

로 줄여 놓았다고 생각하면 된다.


22. 파이썬 re 모듈

파이썬에서 정규식을 사용하려면

import re

를 사용한다.

re는 Regular Expression의 약자이다.

파이썬 표준 라이브러리이므로 별도의 설치는 필요 없다.


23. re.compile()

정규 표현식을 사용할 때 다음과 같이 패턴을 만들 수 있다.

import re

p = re.compile(r"[a-z]+")

여기서

re.compile()

은 작성한 정규식을 파이썬에서 사용할 수 있는 패턴 객체로 만들어 준다.

흐름은 다음과 같다.

정규 표현식

[a-z]+
   ↓
re.compile()
   ↓
Pattern 객체
   ↓
검색 수행

24. [a-z]+ 해석하기

앞에서 배운 문법으로 다음 정규식을 해석해 보자.

[a-z]+

먼저

[a-z]

는

영문 소문자 한 글자

이다.

뒤에

+

가 붙었으므로

한 번 이상 반복

이다.

따라서 최종적으로

[a-z]+

= 영문 소문자가 1글자 이상 연속된 문자열

이라는 의미이다.


25. 정규식을 이용한 문자열 검색

컴파일한 패턴 객체에서는 대표적으로 다음 메서드를 사용할 수 있다.

메서드의미
match()문자열 처음부터 검사
search()문자열 전체에서 검색
findall()매치되는 모든 문자열을 리스트로 반환
finditer()매치되는 결과를 이터레이터로 반환

이 네 개의 차이는 꼭 기억하자.


26. match()

match()는

문자열의 처음부터 패턴과 일치하는지 검사

한다.

먼저 패턴을 만든다.

import re

p = re.compile(r"[a-z]+")

그리고

m = p.match("python")

을 실행한다.

python은 처음부터 영문 소문자로 이루어져 있으므로 매치된다.


매치되지 않는 경우

m = p.match("3 python")

print(m)

결과

None

이 된다.

왜냐하면 문자열의 첫 번째 글자가

3

이기 때문이다.

현재 패턴은

[a-z]+

이므로 첫 번째 위치에서 바로 실패한다.


27. match()의 핵심

정규식

[a-z]+


문자열

python
↑
처음부터 확인

→ O

하지만

3 python
↑
처음 문자가 숫자

→ X

이다.

즉

match()는 문자열 시작 부분이 패턴과 일치해야 한다.


28. match() 결과 활용하기

match()는 성공하면 Match 객체를 반환하고 실패하면 None을 반환한다.

따라서 다음과 같이 사용할 수 있다.

import re

p = re.compile(r"[a-z]+")

m = p.match("python")

if m:
    print("매치되었습니다.")
else:
    print("매치되지 않았습니다.")

29. search()

search()는 match()와 다르게

문자열 전체를 검색

한다.

import re

p = re.compile(r"[a-z]+")

m = p.search("3 python")

print(m)

이번에는 python을 찾을 수 있다.


30. match()와 search() 비교

이 둘은 매우 중요하다.

p.match("3 python")

결과

None

하지만

p.search("3 python")

에서는

python

부분을 찾는다.

정리하면

match()

문자열 시작부터 검사
search()

문자열 전체에서 검색

이다.


그림으로 보면

문자열

3 python
01234567

match()

↓
3 python

첫 위치부터 검사
3이 [a-z]가 아니므로 실패
3 python
  ↑↑↑↑↑↑

문자열 전체를 검색
python 발견

31. findall()

findall()은

정규식과 일치하는 모든 문자열을 찾아 리스트로 반환

한다.

예를 들어

import re

p = re.compile(r"[a-z]+")

result = p.findall("python is very easy")

print(result)

결과

['python', 'is', 'very', 'easy']

이다.


findall의 특징

search()는 일치하는 위치 하나를 찾는 데 주로 사용하는 반면

findall()

은 모든 결과가 필요할 때 유용하다.

문자열

python is very easy

↓ findall()

python
is
very
easy

↓ 리스트

['python', 'is', 'very', 'easy']

32. 숫자를 모두 추출하기

실제 사용에서는 다음처럼 활용할 수 있다.

import re

data = "WEB01=80 WAS01=8080 DB01=3306"

result = re.findall(r"\d+", data)

print(result)

결과

['01', '80', '01', '8080', '01', '3306']

처럼 숫자 패턴을 모두 추출할 수 있다.


33. finditer()

finditer()도 매치되는 결과를 모두 찾는다.

하지만 findall()과 차이가 있다.

import re

p = re.compile(r"[a-z]+")

result = p.finditer("python is easy")

for m in result:
    print(m)

각 결과가 Match 객체 형태로 반환된다.


34. findall()과 finditer() 비교

구분findall()finditer()
모든 결과 검색OO
반환리스트이터레이터
각 값문자열 중심Match 객체
위치 정보 사용직접적이지 않음가능

특히 위치까지 확인해야 한다면

finditer()

가 유용하다.


35. Match 객체

match(), search(), finditer() 등을 사용하면 Match 객체를 얻게 된다.

Match 객체에서는 매치 결과에 대한 정보를 확인할 수 있다.

대표적인 메서드는 다음과 같다.

메서드설명
group()매치된 문자열
start()시작 위치
end()끝 위치
span()(시작, 끝)

36. group()

import re

p = re.compile(r"[a-z]+")

m = p.search("3 python")

print(m.group())

결과

python

즉

group()

은 실제로 매치된 문자열을 반환한다.


37. start()

print(m.start())

매치가 시작된 위치를 반환한다.

문자열이

3 python

이라면 인덱스는

3   p y t h o n
0 1 2 3 4 5 6 7

이므로 python의 시작 위치는

2

이다.


38. end()

print(m.end())

매치가 끝나는 위치를 반환한다.

여기서 주의할 점은 마지막 문자의 인덱스가 아니라 그 다음 위치라는 것이다.

예를 들어

python

이 인덱스 2~7에 있다면

start() → 2
end()   → 8

이 된다.

이 방식은 파이썬 슬라이싱과 같다.

text[2:8]

39. span()

print(m.span())

결과는

(2, 8)

처럼 나온다.

즉

(start(), end())

를 한 번에 튜플로 반환한다.


40. Match 객체 한 번에 보기

import re

p = re.compile(r"[a-z]+")

m = p.search("3 python")

print(m.group())
print(m.start())
print(m.end())
print(m.span())

결과

python
2
8
(2, 8)

따라서

group() → 무엇을 찾았는가?
start() → 어디서 시작했는가?
end()   → 어디까지인가?
span()  → 시작과 끝을 한 번에

라고 기억하면 된다.


41. re.compile() 없이 사용하는 방법

지금까지는

p = re.compile(r"[a-z]+")

m = p.match("python")

처럼 사용했다.

하지만 다음처럼 한 번에 작성할 수도 있다.

m = re.match(r"[a-z]+", "python")

즉

re.compile()
+
match()

↓

re.match()

형태로 사용할 수 있다.


언제 compile을 사용할까?

같은 정규식을 여러 번 사용할 예정이라면

p = re.compile(...)

처럼 패턴 객체를 만들어 두면 코드가 깔끔하다.

간단하게 한 번 검색하는 경우라면

re.search(...)
re.findall(...)

처럼 직접 사용할 수도 있다.


42. 컴파일 옵션

정규식을 사용할 때 동작 방식을 변경하기 위한 옵션이 있다.

대표적인 옵션은 다음과 같다.

옵션축약의미
re.DOTALLre.S.이 줄바꿈까지 포함
re.IGNORECASEre.I대소문자 무시
re.MULTILINEre.M여러 줄에서 ^, $ 적용
re.VERBOSEre.X정규식을 여러 줄과 주석으로 작성

43. DOTALL

기본적으로

.

은 줄바꿈

\n

과 매치되지 않는다.

예를 들어

import re

p = re.compile(r"a.b")

print(p.match("a\nb"))

에서는 매치되지 않는다.


re.DOTALL

다음처럼 옵션을 사용한다.

p = re.compile(r"a.b", re.DOTALL)

또는

p = re.compile(r"a.b", re.S)

그러면

.

이 줄바꿈까지 포함해 매치할 수 있다.

a
\n
b

에서도 매치할 수 있게 된다.


44. IGNORECASE

기본적으로 정규식에서는 대소문자를 구분한다.

python
Python
PYTHON

은 서로 다른 문자열이다.

대소문자를 구분하고 싶지 않다면

re.IGNORECASE

또는

re.I

를 사용한다.

import re

p = re.compile(r"python", re.I)

print(p.match("python"))
print(p.match("Python"))
print(p.match("PYTHON"))

모두 매치할 수 있다.


45. MULTILINE

다음 메타 문자도 자주 사용한다.

^
문자열의 시작

그리고

$

는

문자열의 끝

을 의미한다.

예를 들어

^python

은

python으로 시작

이라는 의미이다.


여러 줄 문자열

다음 데이터가 있다고 해보자.

data = """python one
java two
python three"""

그리고

p = re.compile(r"^python")

을 사용하면 기본적으로 문자열 전체의 처음을 기준으로 한다.

하지만

p = re.compile(r"^python", re.MULTILINE)

또는

p = re.compile(r"^python", re.M)

을 사용하면

각 줄의 시작

을 기준으로 검사할 수 있다.

따라서

python one

과

python three

의 python을 각각 찾을 수 있다.


46. VERBOSE

정규식이 짧을 때는 문제가 없다.

하지만 정규식이 길어지면

^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$

처럼 매우 읽기 어려워진다.

이럴 때

re.VERBOSE

또는

re.X

를 사용할 수 있다.


예제

import re

email_pattern = re.compile(
    r"""
    ^                       # 문자열 시작
    [A-Za-z0-9._%+-]+       # 사용자 이름
    @                       # @
    [A-Za-z0-9.-]+          # 도메인
    \.                      # 실제 점
    [A-Za-z]{2,}            # 최상위 도메인
    $                       # 문자열 끝
    """,
    re.VERBOSE
)

이렇게 작성하면 복잡한 정규식을 여러 줄로 나누고 주석까지 작성할 수 있어 훨씬 이해하기 쉽다.


47. 역슬래시 \ 문제

정규식에서 가장 헷갈릴 수 있는 부분 중 하나가

\

이다.

정규식에서도 역슬래시에 특별한 의미가 있고 파이썬 문자열에서도 역슬래시는 이스케이프 문자로 사용된다.

즉

Python 문자열 해석
        +
정규식 해석

두 단계가 겹칠 수 있다.

그래서 코드가 복잡해질 수 있다.


48. 예를 들어 \section을 찾는다면?

문자열 안에 실제로

\section

이라는 문자가 있다고 해보자.

정규식에서

\section

이라고 그대로 사용하면 문제가 발생할 수 있다.

왜냐하면 정규식 엔진은 앞부분

\s

를

Whitespace

라는 특별한 정규식으로 해석할 수 있기 때문이다.


49. 역슬래시 자체 표현하기

정규식에서 실제 역슬래시를 의미하도록 만들려면 역슬래시를 이스케이프해야 한다.

즉 정규식 수준에서는

\\section

처럼 표현한다.

그런데 일반적인 파이썬 문자열에서도 \가 특별한 의미를 가지므로 코드가 더 복잡해질 수 있다.

이 문제를 쉽게 해결하는 방법이 Raw String이다.


50. Raw String

정규식을 작성할 때 다음처럼 문자열 앞에

r

을 붙이는 경우가 많다.

r"\d+"

이것을 Raw String이라고 한다.


일반 문자열

"\n"

은

줄바꿈

으로 처리된다.

하지만

r"\n"

은 문자열 안의 역슬래시를 정규식 작성에 보다 편리하게 사용할 수 있게 해 준다.


51. 정규식에서는 Raw String을 쓰는 습관

정규식에서는 다음처럼 쓰는 습관을 들이는 것이 좋다.

re.compile(r"\d+")
re.findall(r"[0-9]+", text)
re.search(r"\w+", text)

즉

정규식 문자열
      ↓
가능하면 r"..."

형태로 작성한다고 기억하면 된다.


52. 지금까지 배운 메타 문자

표현의미
[abc]a, b, c 중 하나
[a-z]a~z
[^0-9]숫자가 아닌 문자
\d숫자
\D숫자가 아닌 문자
\s공백 계열
\S공백 계열이 아닌 문자
\w단어 문자
\W단어 문자가 아닌 것
.줄바꿈을 제외한 임의의 한 문자
*앞의 패턴 0번 이상
+앞의 패턴 1번 이상
?앞의 패턴 0번 또는 1번
{m}정확히 m번
{m,n}m~n번

53. 예제를 직접 해석해 보기

다음 정규식을 살펴보자.

\d{3}-\d{4}-\d{4}

하나씩 나누면

\d{3}
 ↓
숫자 3개
-
 ↓
하이픈
\d{4}
 ↓
숫자 4개
-
 ↓
하이픈
\d{4}
 ↓
숫자 4개

따라서 전체적으로

숫자 3개
-
숫자 4개
-
숫자 4개

라는 형태를 찾는다.


54. IP 주소 형태 찾기

아주 단순하게 IP처럼 생긴 문자열을 찾는다면

\d+\.\d+\.\d+\.\d+

처럼 표현할 수도 있다.

하나씩 보면

\d+
 ↓
숫자가 1개 이상

\.
 ↓
실제 점

이 구조가 반복된다.

따라서

192.168.0.1

과 같은 형태를 찾을 수 있다.

다만 이 정규식은 999.999.999.999도 매치할 수 있기 때문에 IPv4 주소의 실제 유효 범위인 0~255까지 검증하는 정규식은 더 복잡하다.


55. 보안 로그 예제로 보기

예를 들어 다음 로그가 있다고 해보자.

SRC=192.168.10.20 DST=10.0.0.10 PORT=443

숫자들을 가져오려면

import re

log = "SRC=192.168.10.20 DST=10.0.0.10 PORT=443"

result = re.findall(r"\d+", log)

print(result)

결과는

['192', '168', '10', '20', '10', '0', '0', '10', '443']

처럼 나온다.

정규식을 조금씩 조합하면 나중에는 로그나 보안 이벤트에서도 원하는 패턴을 추출할 수 있다.


56. 08-2에서 가장 중요한 흐름

정규식을 실제 파이썬 코드에서 사용하면 기본적으로 다음과 같은 흐름이 된다.

정규식 작성
   ↓
re.compile()
   ↓
Pattern 객체
   ↓
문자열 검색
   ↓
match()
search()
findall()
finditer()
   ↓
결과 확인

또는 간단한 경우

re.match()
re.search()
re.findall()

처럼 바로 사용할 수도 있다.


📌 핵심 정리

문자 클래스

[abc]

a 또는 b 또는 c
[a-z]

영문 소문자
[^0-9]

숫자가 아닌 문자

자주 사용하는 문자 클래스

\d → 숫자
\D → 숫자가 아닌 것

\s → 공백 계열
\S → 공백 계열이 아닌 것

\w → 단어 문자
\W → 단어 문자가 아닌 것

반복

*

0번 이상
+

1번 이상
?

0번 또는 1번
{3}

정확히 3번
{2,5}

2~5번

match()

문자열 처음부터 확인
search()

문자열 전체에서 검색

이 차이가 가장 중요하다.


findall

re.findall(r"\d+", "abc 100 def 200")
['100', '200']

매치되는 모든 문자열을 리스트로 반환한다.


finditer

모든 결과를 찾지만 각각의 결과를 Match 객체 형태로 다룰 수 있다.


Match 객체

group()
→ 매치된 문자열

start()
→ 시작 위치

end()
→ 끝 위치

span()
→ (시작 위치, 끝 위치)

컴파일 옵션

re.S
→ .에 줄바꿈 포함

re.I
→ 대소문자 무시

re.M
→ 각 줄에 ^, $ 적용

re.X
→ 복잡한 정규식을 여러 줄과 주석으로 작성

Raw String

정규식에서는 역슬래시가 자주 등장하므로

r"\d+"

처럼 r"..." 형태로 작성하는 습관을 들이면 좋다.


⭐ 08-2 전체 흐름

문자열에서 원하는 규칙 정의
        ↓
정규 표현식 작성
        ↓
[ ]
.
*
+
?
{}
\d
\s
\w
        ↓
re.compile()
        ↓
Pattern 객체 생성
        ↓
 ┌───────────┬───────────┬────────────┬────────────┐
 │           │           │            │
match()   search()    findall()    finditer()
 │           │           │            │
처음부터   전체 검색    모두 리스트   모두 Iterator

그리고 match()나 search()로 얻은 Match 객체에서는

group()
start()
end()
span()

을 이용해

무엇이 매치되었는지
+
어디에서 매치되었는지

확인할 수 있다.

08-2의 핵심은 정규식 기호를 단순히 외우는 것이 아니라 [a-z]+처럼 하나씩 분해해서 읽는 습관을 만드는 것이다.

예를 들어

[a-z]+

를 보면 바로

[a-z]
→ 영문 소문자

+

→ 1번 이상

따라서

영문 소문자가 1글자 이상 연속

이라고 해석할 수 있어야 한다.

profile
성실하자:)

0개의 댓글