본문 바로가기
Python/기초

[파이썬/Python] 정규 표현식 1탄: 메타 문자 활용 및 re 메서드 기초

by 모두의 케빈 2023. 7. 14.

이전 시간에는 정규 표현식의 정의에 대해 배웠습니다. 이번 시간에는 원하는 규칙의 문자열을 얻기 위해 정규 표현식 사이트와 파이썬을 어떻게 활용하는지에 대한 기초적인 실습을 해보도록 하겠습니다.

 

파이썬 정규 표현식


 

파이썬에서는 정규 표현식을 표준 라이브러리인 're'에서 지원합니다. 사용법은 다음과 같습니다.

1. 사용자가 정의한 정규 표현식을 담은 인스턴스(re.Pattern)를 생성한다.

2. 인스턴스의 메서드를 활용하여 정규 표현식에 일치하는 문자열을 매치(match)한다.

# 파이썬 정규 표현식 문법

import re

p = re.compile('사용자가 정의한 정규 표현식')
p.메서드

 

아래 print 문의 출력 결과를 살펴보겠습니다. 're.Pattern'이라는 Class Instance가 생성되어 있습니다. 이 객체가 도대체 무엇일까에 대해서는 아실 필요가 없습니다. 우선은 '아, int나 list처럼 파이썬에서 사용하는 또 다른 자료 유형이구나'라고 받아들여주세요.

p = re.compile('[0-9]')
print(type(p)) # <class 're.Pattern'>

 

 

re 메서드: 정규 표현식을 이용한 문자열 검색


 

정규 표현식을 활용하여 문자열을 검색하기 위해 파이썬에서 지원하는 대표적인 메서드들은 아래 표와 같습니다.

메서드 설명
match 문자열의 처음부터 정규식과 매치되는지 조사한다.
search 문자열 전체를 검색하여 정규식과 매치되는지 조사한다.
findall 정규식과 매치되는 모든 문자열(substring)을 리스트로 리턴한다.
finditer 정규식과 매치되는 모든 문자열(substring)을 반복 가능한 객체로 리턴한다.

 

파이썬에서 정규 표현식을 사용하실 때는 두 가지를 명심하셔야 합니다.

첫째, 정규 표현식이 올바르게 적용되었는가?

둘째, 메서드를 올바르게 활용하고 있는가?

두 번째는 쥬피터 노트북과 같은 파이썬 IDE 환경에서 즉시 확인하실 수 있습니다. 첫 번째는 RegExr 사이트에서 확인하는 것을 추천드리는데요. 화면 한쪽에는 파이썬 IDE, 다른 한쪽에는 RegExr 사이트를 키신 상태에서 따라와 주시기 바랍니다.

 

정규 표현식 사이트의 결과와 일치하도록 적절한 메서드를 사용하자!

정규 표현식을 처음 공부하신 분들이라면 이런 생각을 하실 수 있습니다.

'정규 표현식 사이트와 파이썬, 대체 어떻게 사용하라는거야?'

어렵게 생각하시는 분들이 있을 것 같아서 우선 저의 방법을 말씀드리겠습니다. 저는 먼저 적절한 정규 표현식을 만들기 위해 정규 표현식 사이트를 이용합니다. 그리고 사이트의 결과와 일치하도록 파이썬 환경에서 적절한 메서드를 찾는 방식으로 정규 표현식을 활용합니다.

사용자가 입력한 문자열에서 a,b,c 세 단어를 모두 잡아내는 정규 표현식에 대해 실습해보도록 하겠습니다.

메타 문자 중, 대괄호를 활용하면 되는데요. 메타 문자에서 대괄호는 '['와 ']' 사이의 문자 하나를 검색합니다. 예를 들어, [abc]라고 하면 문자열 중에서 a 또는 b 또는 c 글자 한개를 찾으라는 의미입니다.

먼저 RegExr 사이트에 정규 표현식과 문자열을 입력해보겠습니다. 아래 이미지처럼 윗 칸에는 사용자가 설정한 정규 표현식을 입력 하시고, 아랫 칸에는 문자열을 입력하시면 됩니다. 

 

정규 표현식 사이트 이용 원리

 

문자열에서 a,b,c 단어가 '한 개'씩 모두 체크된 것을 볼 수 있습니다. 이렇게 사이트를 입력한 정규 표현식이 적절하다는 것을 확인했습니다. (이때, 소문자 c와 대문자 C는 다르기 때문에 대문자 C는 검색에서 제외됩니다.)

자 그럼 이제 위의 결과와 동일한 결과를 얻기 위해 적절한 re 메서드를 찾아보겠습니다.

 

사이트 결과와 일치하는 적절한 메서드 찾기

먼저 match 메서드에 대해 살펴보겠습니다. match 메서드는 문자열의 '처음'부터 정규 표현식에 맞는 문자를 탐색합니다. 찾지 못하면 None을 반환하고 찾으면 인덱스와 값을 반환합니다.

sample_str = """I am a boy.
She is a girl.
It is a banana.
He is Charming!"""

p = re.compile('[abc]')
print(p.match(sample_str))

# 위 코드의 결과값
None

 

match 메서드는 문자를 찾아내지 못하고 있습니다. 사이트에서 정규 표현식이 적절한 것을 확인했으니 이는 메서드의 문제입니다. 왜 그럴까요?

아래 코드를 보시면 원리를 이해할 수 있습니다. match 메서드는 문자열의 '처음'부터 찾기 때문에, 첫 시작이 a,b,c가 아니라면 None을 반환하는 것으로 보입니다.

other_str = "banana is good."

p = re.compile('[abc]')
print(p.match(other_str))

# 위 코드의 결과값
<re.Match object; span=(0, 1), match='b'>

 

그럼 search 메서드를 활용해볼까요? 찾긴 찾았는데 'a' 하나만 찾은 것 같습니다. 시작 인덱스가 2이고 끝 인덱스가 3인 것을 보면 I 'a'm에서의 'a'를 찾은 것으로 보입니다. search 메서드는 모든 문자열에서 검색하기 때문에 원하는 문자를 찾을 순 있지만, '한개'만 찾고 바로 검색을 중지하는 것으로 보입니다.

sample_str = """I am a boy.
She is a girl.
It is a banana.
He is Charming!"""

p = re.compile('[abc]')
print(p.search(sample_str))


# 위 코드의 결과값
<re.Match object; span=(2, 3), match='a'>

 

다음으로 findall 메서드를 활용해보겠습니다. 드디어 제가 원하는 결과를 얻었습니다. 문자열 내 모든 a,b,c를 잡아냈네요. findall 메서드는 모든 문자열에서 모든 경우의 수를 탐색하고 그 결과를 리스트로 반환하는 것으로 보입니다.

sample_str = """I am a boy.
She is a girl.
It is a banana.
He is Charming!"""

p = re.compile('[abc]')
print(p.findall(sample_str))

# 위 코드의 결과값
['a', 'a', 'b', 'a', 'a', 'b', 'a', 'a', 'a', 'a']

 

 

 

 

댓글