파이썬
표준 라이브러리
정규표현식 - re
기본 사용법

파이썬 정규표현식 (re 모듈): match, search, findall, replace 특수문자 패턴 예제

이번 포스팅은 파이썬 정규표현식 모듈인 re모듈에 대해서 쉽게 풀어쓴 해설지입니다. 언제나 가장 좋은 자습서는 파이썬 공식 문서입니다. 이 글을 통해, 방향을 잡고나서 해당하는 공식 문서를 읽어나가시면, 내용이 머릿 속에 들어오는 경험을 할 수 있을 것입니다. 그럼 시작할게요!

1. 정규표현식이란?

일반적으로 Regex, 한국어로는 정규식 또는 re 라고 불리는 정규표현식은, 정해진 기호들을 가지고 검색 패턴을 정의하는 방법입니다. 정규식을 사용하면 텍스트 패턴을 매우 유연하고 빠르게 조작하고 찾아낼 수 있기 때문에, 모든 프로그래머가 갖춰야 할 강력한 도구입니다.

파이썬에 내장된 re모듈은 정규표현식으로 작업할 수 있는 강력하고 효율적인 방법을 제공합니다. 내장 모듈이기 때문에, 따로 설치하지 않고도 아래와 같이 import해서 사용가능합니다.

import re

2. 정규표현식 기호 목록

파이썬 정규식은 원시 문자열을 사용한 r"[정규식_패턴]의 형태를 가집니다. 예를 들어, "파이썬"이라는 문자로 시작하는 모든 문자열을 찾아내기 위해서는 r"^파이썬"이라는 정규식 패턴을 사용할 수 있습니다.

다음은 정규식 패턴을 정의할 때 사용하는 기초적인 정규식 기호입니다. 기억하기 쉽게 몇 가지 카테고리로 분류해보았습니다.

  • .: 모든 문자를 의미합니다 (개행 제외).

2.1.문자열의 시작과 끝 (Boundary anchors)

  • ^: 문자열의 시작 부분을 의미합니다.
  • $: 문자열의 끝을 의미합니다.

2.2. 문자열 개수 (Quantifiers)

  • ?: 앞의 문자가 없거나 1개 있는 경우를 의미합니다.
  • *: 앞의 문자가 없거나 하나 이상 있는 경우를 의미합니다.
  • +: 앞의 문자를 하나 이상 있는 경우를 의미합니다.
  • {n}: 앞의 문자가 정확히 n번 나타나는 경우를 의미합니다.
  • {n,}: 앞의 문자가 n개 이상 나타나는 경우를 의미합니다.
  • {n,m}: 앞의 문자가 n개에서 m개 사이로 나타나는 경우를 의미합니다.

2.3. 문자열 형식 (Character classed and sets)

  • \d: 모든 숫자를 의미합니다.
  • \D: 숫자를 제외한 모든 문자를 의미합니다.
  • \s: 스페이스, \t, \n, \r, \f, \v 로 만들어지는 모든 공백을 의미합니다.
  • \S: 공백이 아님을 의미합니다.
  • \w: 모든 알파벳과 숫자, _ 를 의미합니다.
  • \W: 알파벻과 숫자, _를 제외한 모든 문자를 의미합니다.
  • .: \n 를 제회한 모든 문자를 의미합니다.
  • []: 대괄호 안에 속한 모든 문자를 의미합니다.

2.4. 논리 연산자 (Logical operators)

  • (abc): 중괄호 안에 있는 문자 그룹이 그대로 나타나는 경우를 의미하는 그룹 연산자입니다.
  • [^abc]: 대괄호 안의 문자가 아닌 모든 문자가 나타나는 경우를 의미하는 여집합 연산자입니다.
  • (A|B): A 또는 B가 나타나는 경우를 의미하는 OR 연산자입니다.

3. re 모듈 함수 기초

파이썬 re 모듈은 정규 표현식으로 작업할 수 있는 여러 함수를 제공합니다. 가장 일반적으로 사용하는 함수는 다음과 같습니다.

함수를 사용하는 패턴은 섹션 4의 예제를 통해 살펴보겠습니다.

  • re.match(): 문자열의 시작 부분에 정규식 패턴이 일치하는지 확인합니다.
import re
 
pattern = r"Hello"
text = "Hello, World!"
 
match = re.match(pattern, text)
if match:
    print("Match found!")
else:
    print("No match found.")
 
# Output: Match found!
  • re.search(): 문자열 전체에서 정규식 패턴과 일치하는 항목이 있는지 확인합니다.
import re
 
pattern = r"World"
text = "Hello, World!"
 
search = re.search(pattern, text)
if search:
    print("Match found!")
else:
    print("No match found.")
 
# Output: Match found!
  • re.findall(): 문자열에서 서로 겹치지 않는 모든 정규식 패턴을 문자열 리스트로 반환합니다.
import re
 
pattern = r"\d+"
text = "I have 3 apples and 5 oranges."
 
matches = re.findall(pattern, text)
print(matches)
 
# Output: ['3', '5']
  • re.finditer(): 문자열에서 서로 겹치지 않는 모든 정규식 패턴을 yield 하는 Iterator 를 반환합니다.
import re
 
pattern = r"\d+"
text = "I have 3 apples and 5 oranges."
 
matches_iter = re.finditer(pattern, text)
for match in matches_iter:
    print(match.group(), end=" ")
 
# Output: 3 5
  • re.sub(): 문자열에서 정규식 패턴과 일치하는 모든 항목을 지정한 대체 문자열로 교체합니다.
import re
 
pattern = r"apple"
text = "I have an apple. It is a delicious apple."
 
new_text = re.sub(pattern, "orange", text)
print(new_text)
 
# Output: I have an orange. It is a delicious orange.
  • re.split(): 문자열을 정규식 패턴의 발생 횟수에 따라 분할합니다.
import re
 
pattern = r"\s+"
text = "Hello   World!   How are you?"
 
substrings = re.split(pattern, text)
print(substrings)
 
# Output: ['Hello', 'World!', 'How', 'are', 'you?']

4. re 모듈 함수 예제

re 모듈 함수들이 눈에 익었다면, 이제 이 함수들을 사용한 몇 가지 실용적인 예제를 살펴봅시다:

예제 1: 텍스트에서 모든 이메일 주소 찾기

다양한 이메일 주소가 포함된 텍스트가 있고 이를 모두 추출하고 싶다고 가정해 보겠습니다. re.findall() 함수를 사용하여 이를 수행하는 방법은 다음과 같습니다:

import re
 
text = "Contact us at info@example.com or support@example.org for any inquiries."
email_pattern = r"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}"
emails = re.findall(email_pattern, text)
 
print(emails)  # Output: ['info@example.com', 'support@example.org']

예제 2: 텍스트의 URL을 대체 문자열로 바꾸기

여러 URL이 포함된 텍스트가 있고 이를 [URL] 과 같은 대체 문자열로 바꾸고 싶다고 가정해 봅시다. 이 작업에는 re.sub() 함수를 사용할 수 있습니다:

import re
 
text = "Visit our website at https://example.com and check our blog at https://blog.example.com."
url_pattern = r"https?://[^\s]+"
replaced_text = re.sub(url_pattern, "[URL]", text)
 
print(replaced_text)  # Output: Visit our website at [URL] and check our blog at [URL].

예제 3: 다양한 형식의 전화번호 추출하기

다양한 형식의 텍스트에서 re.finditer() 함수를 이용해 전화번호를 추출해보겠습니다.

import re
 
text = "Call John at (123) 456-7890 or reach Jane at 987-654-3210 for more information."
phone_pattern = r"\(?\d{3}\)?[-\s]?\d{3}[-\s]?\d{4}"
phone_numbers = [match.group() for match in re.finditer(phone_pattern, text)]
 
print(phone_numbers)  # Output: ['(123) 456-7890', '987-654-3210']

예제 4: 비밀번호 검증하기

이 예제에서는, 사용자가 입력한 비밀번호가 대문자 1개 이상, 소문자 1개 이상, 숫자 1개 이상, 총 글자 8자 이상 등의 기준을 충족하는지 확인합니다. 이 작업에는 re.search() 를 사용합니다.

import re
 
def is_valid_password(password):
    if len(password) < 8:
        return False
    if not re.search(r"[A-Z]", password):
        return False
    if not re.search(r"[a-z]", password):
        return False
    if not re.search(r"\d", password):
        return False
    return True
 
password = "P4ssw0rd!"
print(is_valid_password(password))  # Output: True

예제 5: 여러 가지 기호를 기준으로 문자열 자르기

이 예제에서는 re.split() 함수를 사용하여 여러 구분 기호(쉼표, 세미콜론, 파이프)를 사용하여 문자열을 분할하겠습니다:

import re
 
text = "apple,banana;orange|grape"
delimiter_pattern = r"[,;|]"
fruits = re.split(delimiter_pattern, text)
 
print(fruits)  # Output: ['apple', 'banana', 'orange', 'grape']

5. 한 걸음 더 나아가기

정규식 기초 문법과 함수 외에도 정규식에 대해 깊이 공부할 만 한 주제들이 있습니다.

  • Lookahead 와 lookbehind assertion: 특정 정규식 패턴에 추가적인 패턴을 등록하는 방법입니다.
  • Named groups 과 backreferences: 정규식에서 자료구조, 변수와 비슷한 테크닉을 사용하는 방법입니다.
  • Non-capturing groups: group 을 사용할 때, 패턴 검색에는 사용하지만 그 값은 무시하는 테크닉입니다.

그 외에도 케이스에 상관없이 검색하는 방법, 여러 줄 모드 등 더 유용한 기법들을 함께 알아보세요.

6. re 모듈을 사용하는 팁

다음은 정규 표현식으로 작업할 때 더 쉽게 사용할 수 있는 몇 가지 팁과 요령입니다:

  • 정규식 패턴에 원시 문자열(r"")을 사용하여 백슬래시를 이스케이프할 필요가 없도록 하세요. 파이썬에서 정규식을 위한 역슬래시를 사용하려면 이스케이프가 필요하지만 원시 문자열 (Raw string) 을 사용하면, 그럴 필요가 없습니다.
  • Regex101 은 정규식 패턴을 테스트하고 디버그할 수 있는 간편한 온라인 도구입니다. 한 번만 익혀두면 꾸준히 사용하게 될 것입니다.
  • 복잡한 정규식 패턴을 하나로 만들면 가독성도 떨어지고 관리가 어렵습니다. 더 작고 관리하기 쉬운 단위로 나누어 가독성과 유지보수 가능성을 높입니다.
  • 주석과 상세 모드(re.VERBOSE)를 사용하면 정규식 패턴을 더 이해하기 쉽게 만들 수 있습니다. re.compile()과 함께 사용하여 상세한 주석을 추가할 수 있습니다.

7. 마치며

정규식은 파이썬에서 텍스트 조작과 패턴 검색을 위한 강력한 도구입니다. re 모듈을 익히고 정규식 기초 문법을 이해하면, 다양한 텍스트 작업을 쉽게 처리할 수 있습니다.

copyright for Python re basics

© 2023 All rights reserved.