파이썬 정규표현식 : 정규표현식 정리, 패턴 모음

정규표현식(Regular Expression)은 특정한 규칙을 가진 문자열의 패턴을 표현하는 문자열입니다. 아주 처음 “파이썬 정규표현식” 개념을 마주했을 때는 한 줄기의 빛이였습니다. “그 때는 파이썬 최고야 공부를 시작하길 잘했어” 라며 스스로를 칭찬까지 했습니다…ㅎ.

물론 정규표현식 개념은 파이썬 말고도 다른 언어에서도 존재하며 곳곳에서 많이 사용됩니다. 저는 파이썬이 주언어라 파이썬에서 많이 사용했는데요.

이메일 형식의 판단, 전화번호 형식 판별, 숫자로만 이루어진 문자열 찾기 등 많은 일들을 할 수 있습니다

파이썬에서는 re 모듈을 통해 정규표현식을 사용할 수 있습니다.

간단한 정규표현식 예제

우선 문자열에서 2자리 이상의 수를 찾고 싶다는 가정을 하면 정규표현식을 아래와 같이 활용할 수 있습니다.

import re

# 정규표현식 패턴 정의
#raw string : 문자열앞에 r을 붙혀서 해당 문자열의 구성을 그대로 문자열로 변환
pattern = r'\d{2,4}'

# 대상 문자열
text = "2022년은 4자리 숫자입니다."

# 정규표현식 검색
match = re.search(pattern, text)

# 결과 출력
if match:
    print("찾은 결과:", match.group())  # 찾은 결과: 2022
else:
    print("일치하는 패턴이 없습니다.")

코드를 보면 패턴을 정의하고, 정의한 패턴이 있는지 찾고, 찾은 패턴을 추출할 수 있다는 것을 확인 할 수 있습니다.

  • \d{2,4}: 숫자가 2~4회까지 나타남을 의미하는 패턴. 대상 문자열에서 찾을 패턴을 정의한 것
  • re.search(pattern, text) : 문자열에서 패턴을 찾음
  • match.group() : re.search에서 반환 된 값을 가진 match에서 group() 메소드를 통해 반환 된 값을 확인

찾은 문자열, 시작 인덱스, 마지막 인덱스 찾기

찾는 문자열 패턴의 문자열, 문자열 시작, 끝 위치를 정보를 알 수 있습니다.

import re

m = re.search(r'abc1', '123abc1def')
print(type(m))  # <class 're.Match'>
print(m)  # <re.Match object; span=(3, 7), match='abc1'>
print(m.start())    # 찾은 문자열의 시작 인덱스 (결과 : 3)
print(m.end())      # 찾은 문자열의 마지막 인덱스 (결과 : 7)
print(m.group())    # 찾은 문자열 # 매개변수에 인덱스 넣어서 특정 문자열만 뽑을 수 있다 (결과 : abc1)

m : match 객체, 이는 매치된 부분의 정보를 담고 있는 객체입니다.

start() : 매치된 부분의 시작 인덱스를 출력

end() : 매치된 부분의 마지막 인덱스를 출력

group() : 매치된 부분의 문자열 출력

일치한 패턴이 없을 시에는 None을 반환하는 것에 유의합니다.

import re

m = re.search(r'ESG', '123abc1def')
print(type(m))  # <class 'NoneType'>
print(m)  # None

정규표현식 검색 방법

re 라이브러리에는 정규표현식으로 검색하는 4가지 방법이 있습니다.

메서드 내용
 match(pattern, string) 문자열의 시작 부분부터 매칭이 되는지 검색.
 search(pattern, string) 문자열에 패턴과 매칭되는 곳이 있는지 검색.
 findall(pattern, string) 정규식과 매치되는 모든 문자열을 리스트로 반환.
 finditer(pattern, string) 정규식과 매치되는 모든 문자열을 iterator 객체로 반환.

match(pattern, string) : 문자열의 시작 부분에서 패턴이 일치하는지 테스트

import re

pattern = r'\d+'  # Match one or more digits
string = '123abc'

result = re.match(pattern, string)

if result:
    print("Match found:", result.group())   # Match found: 123
else:
    print("No match at the beginning of the string.")

search(pattern, string) : 전체 문자열에서 일치하는 항목을 검색하고 첫 번째 항목을 반환

import re

pattern = r'\d+'  # Match one or more digits
string = 'abc123def345'

result = re.search(pattern, string)

if result:
    print("Match found:", result.group())  # Match found: 123
else:
    print("No match in the string.")

findall(pattern, string) : 문자열에서 패턴이 일치하는 모든 항목을 찾아 리스트로 반환

import re

pattern = r'\d+'  # Match one or more digits
string = 'abc123def456ghi'

result = re.findall(pattern, string)

if result:
    print("Matches found:", result)  # Matches found: ['123', '456']
else:
    print("No matches in the string.")

finditer(pattern, string) : 문자열에서 패턴의 모든 항목을 찾아서 iterator로 반환

import re

pattern = r'\d+'  # Match one or more digits
string = 'abc123def456ghi'

result_iterator = re.finditer(pattern, string)

for result in result_iterator:
    print("Match found:", result.group())
    """
    Match found: 123
    Match found: 456
    """

정규표현식 정리

정규표현식설명
[ ]괄호 안의 문자 중 하나와 일치
[ – ]범위 내의 문자 중 하나와 일치
[^0-9]숫자가 아닌 경우에 일치
\w알파벳, 대소문자, 숫자와 일치
\W알파벳 대소문자, 숫자가 아닌 것과 일치
\s공백문자와 일치
\S공백이 아닌 것과 일치
\d숫자 character와 일치
\D숫자가 아닌 것과 일치
\b단어 구분자(Word boundary)
\B\b의 반대로, whitespace로 구분되지 않은 경우에만 일치
.줄바꿈 문자인 \n을 제외한 모든 문자와 일치
\.점(.)과 일치
()특정 그룹을 찾는다
^문자열의 맨 처음과 일치
$문자열의 끝과 일치
+바로 앞 문자가 1번 이상 반복되는 패턴에 일치
*바로 앞 문자가 0번 이상 반복되는 패턴에 일치
?바로 앞 문자가 0번 또는 1번 발생하는 패턴에 일치
{ }반복의 횟수를 지정하는 패턴에 일치
{ , }반복의 최소 횟수와 최대 횟수를 지정하는 패턴에 일치
{ , }?반복의 최소 횟수만 지정하고 최대 횟수는 맞지 않는 경우에 일치

정규표현식 예제

[ ] : 괄호 안의 문자 중 하나와 일치

import re

# 검색할 문자열
text = "Character classes example: abc123"

# a,b,c 중 하나에 매치되는 부분을 찾아 출력
matches = re.findall(r'[abc]', text)

# findall 결과 출력
print("Matches for [abc]:", matches)  
# Matches for [abc]: ['a', 'a', 'c', 'c', 'a', 'a', 'a', 'b', 'c']

위의 코드에서 [abc]는 ‘a’, ‘b’, ‘c’ 중 하나에 매치되는 부분을 찾습니다. findall 함수를 사용하여 매치된 부분을 리스트로 반환하고, 이를 출력합니다.

[ – ] : 범위 내의 문자 중 하나와 일치

[ ]괄호 안의 '-'하이픈은 범위 중 하나 일치하는 것을 찾는 정규표현식 패턴입니다.

[a-zA-Z] 를 예로 들면, 이는 알파벳 대소문자 중 하나와 일치하는 것을 나타내는 정규표현식 패턴입니다.

import re

# 정규표현식 패턴: 소문자 또는 대문자 알파벳 중 하나와 일치
pattern = r'[a-zA-Z]'

# 대상 문자열
string_value = 'AbC123'

# findall 함수를 사용하여 문자열에서 패턴과 일치하는 모든 항목 찾기
result = re.findall(pattern, string_value)

# 결과 출력
if result:
    print("일치하는 항목:", result)  # 일치하는 항목: ['A', 'b', 'C']
else:
    print("문자열에서 일치하는 항목을 찾을 수 없습니다.")

[^0-9] : 숫자가 아닌 경우에 일치

\D와 동일한 정규표현식 패턴입니다.

import re

# 정규표현식 패턴: 숫자가 아닌 모든 문자와 일치
pattern = r'[^0-9]'

# 대상 문자열
string_value = 'A1B2C3'

# findall 함수를 사용하여 문자열에서 패턴과 일치하는 모든 항목 찾기
result = re.findall(pattern, string_value)

# 결과 출력
if result:
    print("일치하는 항목:", result)  # 일치하는 항목: ['A', 'B', 'C']
else:
    print("문자열에서 일치하는 항목을 찾을 수 없습니다.")

\w, \W : 알파벳, 대소문자, 숫자

import re

# 검색할 문자열
text = "Hello123, this is an example with multiple words"

# \w+에 매치되는 모든 부분을 찾아 출력
matches_w = re.findall(r'\w+', text)

# \W+에 매치되는 모든 부분을 찾아 출력
matches_W = re.findall(r'\W+', text)

# findall 결과 출력
print("Matches for \\w:", matches_w)
# Matches for \w: ['Hello123', 'this', 'is', 'an', 'example', 'with', 'multiple', 'words']
print("Matches for \\W:", matches_W)
#Matches for \W: [', ', ' ', ' ', ' ', ' ', ' ', ' ']

\s, \S : 공백

import re

# 검색할 문자열
text = "Whitespace separation example with \ttabs\tand\nnewlines."

# \s+에 매치되는 모든 부분을 찾아 출력
matches_s = re.findall(r'\s+', text)

# \S+에 매치되는 모든 부분을 찾아 출력
matches_S = re.findall(r'\S+', text)

# findall 결과 출력
print("Matches for \\s:", matches_s)  
# Matches for \s: [' ', '\t', '\t', '\n']

print("Matches for \\S:", matches_S)
# Matches for \S: ['Whitespace', 'separation', 'example', 'with', 'tabs', 'and', 'newlines.']

\d, \D : 숫자

import re

# 정규표현식 패턴: 숫자와 일치
pattern_digit = r'\d'

# 정규표현식 패턴: 숫자가 아닌 것과 일치
pattern_non_digit = r'\D'

# 대상 문자열
string_value = '123abc456!'

# findall 함수를 사용하여 문자열에서 각 패턴과 일치하는 모든 항목 찾기
result_digit = re.findall(pattern_digit, string_value)
result_non_digit = re.findall(pattern_non_digit, string_value)

# 결과 출력
if result_digit:
    print("숫자와 일치하는 항목:", result_digit)  # 숫자와 일치하는 항목: ['1', '2', '3', '4', '5', '6']
else:
    print("숫자와 일치하는 항목을 찾을 수 없습니다.")

if result_non_digit:
    print("숫자가 아닌 항목:", result_non_digit)  # 숫자가 아닌 항목: ['a', 'b', 'c', '!', '_']
else:
    print("숫자가 아닌 항목을 찾을 수 없습니다.")

\b, \B : 단어 구분자

import re

print(re.search(r'\bclass\b', 'this is a class room'))  # <re.Match object; span=(10, 15), match='class'>
print(re.search(r'\bclass\b', 'this is a class'))  # <re.Match object; span=(10, 15), match='class'>
print(re.search(r'\bclass\b', 'AclassA'))  # None

print(re.search(r'\Bclass\B', 'this is a class room'))  # None
print(re.search(r'\Bclass\B', 'this is a class'))  # None
print(re.search(r'\Bclass\B', 'AclassA'))  # <re.Match object; span=(1, 6), match='class'>

. : 줄바꿈 제외 문자

\S처럼 모든 형태의 공백 제외가 아닌 줄바꿈만 제외한 문자

import re

# 정규표현식 패턴: 마침표(.)와 일치
pattern_dot = r'.'

# 대상 문자열
string_value = 'Hello World!\nThis is Python'

# findall 함수를 사용하여 문자열에서 패턴과 일치하는 모든 항목 찾기
result_dot = re.findall(pattern_dot, string_value)

# 결과 출력
if result_dot:
    print("줄 바꿈 제외 문자:", result_dot)  # 줄 바꿈 제외 문자: ['H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', '!', 'T', 'h', 'i', 's', ' ', 'i', 's', ' ', 'P', 'y', 't', 'h', 'o', 'n']
else:
    print("줄 바꿈 제외 문자 항목을 찾을 수 없습니다.")

: 점

그냥 '.' 점은 줄바꿈 제외 문자를 의미합니다. ‘\.’과 같이 점 앞에 이스케이프를 표기해줘야 점을 찾습니다.

import re

# 정규표현식 패턴: 백슬래시(\)로 이스케이프한 마침표(.)와 일치
pattern_escaped_dot = r'\.'

# 대상 문자열
string_value = 'example.com has a dot.'

# findall 함수를 사용하여 문자열에서 패턴과 일치하는 모든 항목 찾기
result_escaped_dot = re.findall(pattern_escaped_dot, string_value)

# 결과 출력
if result_escaped_dot:
    print("이스케이프된 마침표와 일치하는 항목:", result_escaped_dot)  # 이스케이프된 마침표와 일치하는 항목: ['.']
else:
    print("이스케이프된 마침표와 일치하는 항목을 찾을 수 없습니다.")

() : 특정 그룹

괄호를 사용하여 특정 그룹을 찾을 수 있습니다. 밑의 예제를 확인해주세요.

import re

# 정규표현식 패턴: 괄호를 사용하여 특정 그룹을 형성
pattern_with_group = r'(\d{3})-(\d{4})'

# 대상 문자열
string_value = 'Phone numbers: 123-4567, 987-6543'

# search 함수를 사용하여 문자열에서 패턴과 일치하는 첫 번째 항목 찾기
match_with_group = re.search(pattern_with_group, string_value)

# 결과 출력
if match_with_group:
    # group(0)은 전체 패턴과 일치하는 문자열
    print("전체 패턴과 일치하는 문자열:", match_with_group.group(0))  
    # 전체 패턴과 일치하는 문자열: 123-4567
    
    # group(1)은 첫 번째 그룹 (\d{3})에 해당하는 문자열
    print("첫 번째 그룹에 일치하는 문자열:", match_with_group.group(1))  
    # 첫 번째 그룹에 일치하는 문자열: 123
    
    # group(2)은 두 번째 그룹 (\d{4})에 해당하는 문자열
    print("두 번째 그룹에 일치하는 문자열:", match_with_group.group(2))  
    # 두 번째 그룹에 일치하는 문자열: 4567
else:
    print("일치하는 패턴을 찾을 수 없습니다.")

이 코드에서 정규표현식 패턴 (\d{3})-(\d{4})의 ‘()’는 괄호 안에 있는 부분을 하나의 그룹으로 묶어주는 역할을 합니다. 각각의 괄호 안에 있는 부분은 하나의 서브그룹이 됩니다.

(\d{3}): 첫 번째 그룹으로, 숫자(\d)가 3번 반복되는 패턴을 의미합니다. 이는 전화번호의 첫 세 자리에 해당합니다.

(\d{4}): 두 번째 그룹으로, 숫자(\d)가 4번 반복되는 패턴을 의미합니다. 이는 전화번호의 나머지 네 자리에 해당합니다.

^ : 문자열의 처음

해당 문자열 패턴으로 시작하는 것을 찾습니다. match()을 이용한 검색 결과와 동일한 결과를 가집니다.

import re

# 정규표현식 패턴: '^' 사용 여부에 따라 일치하는 문자열 찾기
pattern_with_anchor = r'^The'
pattern_without_anchor = r'The'

# 대상 문자열
string_value = 'The quick brown fox jumps over the lazy dog. The end.'

# findall 함수를 사용하여 문자열에서 패턴과 일치하는 모든 항목 찾기
matches_with_anchor = re.findall(pattern_with_anchor, string_value)
matches_without_anchor = re.findall(pattern_without_anchor, string_value)

# 결과 출력
print(f"패턴 {pattern_with_anchor}와 일치하는 문자열: {matches_with_anchor}")
# 패턴 ^The와 일치하는 문자열: ['The']
print(f"패턴 {pattern_without_anchor}와 일치하는 문자열: {matches_without_anchor}")
# 패턴 The와 일치하는 문자열: ['The', 'The']

^‘는 문자열의 시작과 매치되므로, 패턴 ‘^The‘는 문자열의 시작에서 ‘The‘와 일치하는 경우에만 찾습니다. 반면에 패턴 ‘The‘는 문자열 어디에서든 ‘The‘를 찾습니다.

$ : 문자열의 끝

import re

# 정규표현식 패턴: '$' 사용 여부에 따라 일치하는 문자열 찾기
pattern_with_anchor = r'\d+$'
pattern_without_anchor = r'\d+'

# 대상 문자열 (숫자가 아닌 문장)
string_value = 'The price is $123.45 and it keeps increasing.'

# findall 함수를 사용하여 문자열에서 패턴과 일치하는 모든 항목 찾기
matches_with_anchor = re.findall(pattern_with_anchor, string_value)
matches_without_anchor = re.findall(pattern_without_anchor, string_value)

# 결과 출력
print(f"패턴 {pattern_with_anchor}와 일치하는 문자열: {matches_with_anchor}")
# 패턴 \d+$와 일치하는 문자열: []
print(f"패턴 {pattern_without_anchor}와 일치하는 문자열: {matches_without_anchor}")
# 패턴 \d+와 일치하는 문자열: ['123', '45']

$‘는 문자열의 끝과 매치되므로, 패턴 ‘\d+$‘는 숫자가 문자열의 끝에 있는 경우에만 일치합니다. 패턴 ‘\d+‘는 문자열에서 연속된 숫자를 찾는 일반적인 패턴이므로, 숫자가 어디에 있든 모두 일치합니다.

+ : 1번 이상 반복

import re

# 정규표현식 패턴: '+' 사용 여부에 따라 일치하는 문자열 찾기
pattern_with_plus = r'\d+'
pattern_without_plus = r'\d'

# 대상 문자열
string_value = '12345'

# findall 함수를 사용하여 문자열에서 패턴과 일치하는 모든 항목 찾기
matches_with_plus = re.findall(pattern_with_plus, string_value)
matches_without_plus = re.findall(pattern_without_plus, string_value)

# 결과 출력
print(f"패턴 {pattern_with_plus}와 일치하는 문자열: {matches_with_plus}")
# 패턴 \d+와 일치하는 문자열: ['12345']
print(f"패턴 {pattern_without_plus}와 일치하는 문자열: {matches_without_plus}")
# 패턴 \d와 일치하는 문자열: ['1', '2', '3', '4', '5']

+‘는 앞의 문자가 1번 이상 반복될 때 일치하므로 +‘를 사용하면 연속된 숫자를 하나의 항목으로 인식합니다.

* : 0번 이상 반복

import re

# 정규표현식 패턴: '*' 사용 여부에 따라 일치하는 문자열 찾기
pattern_with_asterisk = r'\d*'
pattern_without_asterisk = r'\d'

# 대상 문자열
string_value = '12345'

# findall 함수를 사용하여 문자열에서 패턴과 일치하는 모든 항목 찾기
matches_with_asterisk = re.findall(pattern_with_asterisk, string_value)
matches_without_asterisk = re.findall(pattern_without_asterisk, string_value)

# 결과 출력
print(f"패턴 {pattern_with_asterisk}와 일치하는 문자열: {matches_with_asterisk}")
# 패턴 \d*와 일치하는 문자열: ['12345', '']
print(f"패턴 {pattern_without_asterisk}와 일치하는 문자열: {matches_without_asterisk}")
# 패턴 \d와 일치하는 문자열: ['1', '2', '3', '4', '5']

”는 앞의 문자가 0번 이상 반복될 때 일치하므로 ”를 사용하면 숫자가 여러 번 반복되거나 전혀 없는 경우에도 일치합니다.

{} : 반복 지정

import re

# 정규표현식 패턴: '{4}' 사용 여부에 따라 일치하는 문자열 찾기
pattern_with_repeat = r'\d{4}'
pattern_without_repeat = r'\d'

# 대상 문자열
string_value = '12345'

# findall 함수를 사용하여 문자열에서 패턴과 일치하는 모든 항목 찾기
matches_with_repeat = re.findall(pattern_with_repeat, string_value)
matches_without_repeat = re.findall(pattern_without_repeat, string_value)

# 결과 출력
print(f"패턴 {pattern_with_repeat}와 일치하는 문자열: {matches_with_repeat}")
# 패턴 \d{4}와 일치하는 문자열: ['1234']
print(f"패턴 {pattern_without_repeat}와 일치하는 문자열: {matches_without_repeat}")
# 패턴 \d와 일치하는 문자열: ['1', '2', '3', '4', '5']

{4}‘를 사용하면 앞의 문자가 정확히 4번 반복될 때 일치하므로, 이 경우에는 연속된 4자리 숫자를 찾습니다.

{,} : 반복 범위 지정

import re

# 정규표현식 패턴: '{}' 사용 여부에 따라 일치하는 문자열 찾기
pattern_with_braces = r'\d{2,4}'
pattern_without_braces = r'\d'

# 대상 문자열
string_value = '12345'

# findall 함수를 사용하여 문자열에서 패턴과 일치하는 모든 항목 찾기
matches_with_braces = re.findall(pattern_with_braces, string_value)
matches_without_braces = re.findall(pattern_without_braces, string_value)

# 결과 출력
print(f"패턴 {pattern_with_braces}와 일치하는 문자열: {matches_with_braces}")
# 패턴 \d{2,4}와 일치하는 문자열: ['1234']
print(f"패턴 {pattern_without_braces}와 일치하는 문자열: {matches_without_braces}")
# 패턴 \d와 일치하는 문자열: ['1', '2', '3', '4', '5']

{2,4}‘를 사용하면 앞의 문자가 지정한 범위 내에서 반복될 때 일치하므로, 이 경우에는 2부터 4번까지의 연속된 숫자를 찾습니다.

{,}? : 최소 반복 범위 지정

import re

# 정규표현식 패턴: '{2,4}?' 사용 여부에 따라 일치하는 문자열 찾기
pattern_with_repeat_lazy = r'\d{2,4}?'
pattern_with_repeat_greedy = r'\d{2,4}'

# 대상 문자열
string_value = '12345'

# findall 함수를 사용하여 문자열에서 패턴과 일치하는 모든 항목 찾기
matches_with_repeat_lazy = re.findall(pattern_with_repeat_lazy, string_value)
matches_with_repeat_greedy = re.findall(pattern_with_repeat_greedy, string_value)

# 결과 출력
print(f"패턴 {pattern_with_repeat_lazy}와 일치하는 문자열: {matches_with_repeat_lazy}")
# 패턴 \d{2,4}?와 일치하는 문자열: ['12', '34']
print(f"패턴 {pattern_with_repeat_greedy}와 일치하는 문자열: {matches_with_repeat_greedy}")
# 패턴 \d{2,4}와 일치하는 문자열: ['1234']

{2,4}?‘는 앞의 문자가 2번에서 4번까지 최소 횟수로 반복될 때 일치하므로, 가능한 적은 숫자를 찾습니다. 그에 반해 ‘{2,4}‘는 가능한 많은 숫자를 찾으려고 하므로 최대 횟수로 반복되는 경우에 일치합니다.

complie() : 패턴 저장

re.compile() 메소드는 정규표현식 패턴을 미리 컴파일하여 객체로 저장하는 함수입니다. 이를 통해 여러 번 사용되는 패턴을 미리 컴파일하여 성능을 향상시킬 수 있습니다.

예를 들어, 동일한 패턴을 여러 번 사용해야 할 때 매번 패턴을 다시 컴파일하는 대신, re.compile()을 사용하여 패턴을 미리 컴파일하고 나중에 사용할 수 있습니다.

아래는 re.compile() 메소드의 사용 예제입니다

import re

# 정규표현식 패턴을 컴파일하여 객체로 저장
pattern = re.compile(r'\d{3}-\d{4}')

# 대상 문자열
string_value = 'Phone numbers: 123-4567, 987-6543'

# 컴파일된 패턴 객체를 사용하여 검색
match_result = pattern.search(string_value)

# 결과 출력
if match_result:
    print("매치된 문자열:", match_result.group())
    # 매치된 문자열: 123-4567
else:
    print("일치하는 패턴을 찾을 수 없습니다.")

이렇게 컴파일된 패턴 객체를 사용하면 코드의 가독성이 향상되고, 동일한 패턴을 반복해서 사용할 때 성능이 개선됩니다.

sub() : 패턴 변경

re.sub() 메소드는 정규표현식에 매치되는 부분을 다른 문자열로 치환하는 함수입니다. 이를 통해 문자열에서 특정 부분을 찾아 바꿀 수 있습니다.

re.sub() 메소드의 기본 구조는 다음과 같습니다

re.sub(pattern, repl, string, count=0, flags=0)
  • pattern: 찾을 정규표현식 패턴
  • repl: 대체할 문자열
  • string: 대상 문자열
  • count: 치환할 횟수 (기본값은 0으로 모두 치환)
  • flags: 정규표현식의 플래그 (옵션)

아래는 complie() 메소드와 sub() 메소드를 함께 사용한 예제입니다

import re

# 정규표현식 패턴
pattern = re.compile(r'\d{3}-\d{4}')

# 대상 문자열
string_value = 'Phone numbers: 123-4567, 987-6543'

# 정규표현식에 매치되는 부분을 'XXX-XXXX'로 치환
modified_string = pattern.sub('XXX-XXXX', string_value)

# 결과 출력
print("변경 전 문자열:", string_value)
# 변경 전 문자열: Phone numbers: 123-4567, 987-6543
print("변경 후 문자열:", modified_string)
# 변경 후 문자열: Phone numbers: XXX-XXXX, XXX-XXXX

위 예제에서는 전화번호 형식인 ‘123-4567’과 ‘987-6543’을 정규표현식에 매치되는 부분을 ‘XXX-XXXX’로 치환하여 변경하였습니다.

IGNORECASE : 대소문자 무시 플래그

re.IGNORECASE 또는 re.I는 정규표현식 검색 시 대소문자를 구별하지 않도록 하는 플래그입니다. 이 플래그를 사용하면 대소문자를 구분하지 않고 일치하는 부분을 찾을 수 있습니다.

아래는 re.IGNORECASE를 사용한 예제 코드입니다

import re

# 대소문자를 구별하여 'apple'이라는 단어 찾기
pattern_case_sensitive = re.compile(r'apple')

# 대상 문자열
string_value = 'I have an Apple and an apple.'

# 대소문자를 구별하여 'apple'이라는 단어 찾기
matches_case_sensitive = pattern_case_sensitive.findall(string_value)

# 결과 출력
print("대소문자를 구별하여 찾은 단어:", matches_case_sensitive)
# 대소문자를 구별하여 찾은 단어: ['apple']



# 대소문자를 구별하지 않고 'apple'이라는 단어 찾기
pattern_ignore_case = re.compile(r'apple', flags=re.IGNORECASE)

# 대소문자를 구별하지 않고 'apple'이라는 단어 찾기
matches_ignore_case = pattern_ignore_case.findall(string_value)

# 결과 출력
print("대소문자를 구별하지 않고 찾은 단어:", matches_ignore_case)
# 대소문자를 구별하지 않고 찾은 단어: ['Apple', 'apple']

위 코드에서는 대소문자를 구별하여 ‘apple’을 찾는 패턴과 대소문자를 구별하지 않고 찾는 패턴을 비교하였습니다. 첫 번째 패턴은 “apple”만 찾았지만, 두 번째 패턴은 대소문자를 구별하지 않아 “Apple”과 “apple”을 모두 찾아냈습니다.

MULTILINE : 모든 줄에서 검사 플래그

re.MULTILINE 플래그는 정규표현식의 ^$ 메타문자의 동작을 변경하는데 사용됩니다. 기본적으로 ^는 문자열의 처음, $는 문자열의 끝과만 매치되지만, re.MULTILINE을 사용하면 각 줄의 처음과 끝과도 매치됩니다.

다음은 re.MULTILINE 플래그를 사용하는 예제 코드입니다

import re

# 대상 문자열
string_value = """Hello, World!
Python is awesome
Regex is powerful
"""

# 정규표현식 패턴
pattern = r'^Python'

# MULTILINE 플래그를 사용하지 않았을 때
result_without_multiline = re.search(pattern, string_value)
print("Without MULTILINE:")
print(result_without_multiline.group() if result_without_multiline else "No match")
# Without MULTILINE:
# No match

# MULTILINE 플래그를 사용했을 때
result_with_multiline = re.search(pattern, string_value, re.MULTILINE)
print("\nWith MULTILINE:")
print(result_with_multiline.group() if result_with_multiline else "No match")
# With MULTILINE:
# Python

위 코드에서 ^Python 패턴은 문자열의 처음에서만 매치되기 때문에 re.MULTILINE을 사용하지 않으면 결과가 없습니다. 그러나 re.MULTILINE을 사용하면 각 줄의 처음에서도 매치되어 “Python”을 찾을 수 있습니다.

참고하면 좋은 글

https://docs.python.org/3/howto/regex.html

Leave a Comment

목차