소개
정규 표현식 캡처 그룹 (capture groups) 은 Python 에서 텍스트 데이터를 추출하고 조작하는 강력한 도구입니다. 이 랩에서는 캡처 그룹 사용의 필수 기술을 배우고, 이러한 고급 패턴 매칭 메커니즘이 복잡한 문자열 파싱 및 데이터 추출 작업을 어떻게 단순화할 수 있는지에 대한 실질적인 통찰력을 제공합니다.
정규 표현식 캡처 그룹 (capture groups) 은 Python 에서 텍스트 데이터를 추출하고 조작하는 강력한 도구입니다. 이 랩에서는 캡처 그룹 사용의 필수 기술을 배우고, 이러한 고급 패턴 매칭 메커니즘이 복잡한 문자열 파싱 및 데이터 추출 작업을 어떻게 단순화할 수 있는지에 대한 실질적인 통찰력을 제공합니다.
캡처 그룹은 정규 표현식에서 일치하는 패턴의 특정 부분을 추출하고 그룹화할 수 있는 강력한 기능입니다. Python 에서는 정규 표현식 패턴 내에서 괄호 ()를 사용하여 정의됩니다.
기본 캡처 그룹 사용법을 시연하기 위해 Python 스크립트를 만들어 보겠습니다.
WebIDE 에서 통합 터미널을 열고, 아직 해당 디렉토리에 있지 않다면 프로젝트 디렉토리로 이동합니다.
cd ~/project
touch 명령을 사용하여 basic_capture.py라는 새 파일을 만듭니다.
touch basic_capture.py
WebIDE 편집기에서 basic_capture.py를 열고 다음 Python 코드를 추가합니다.
import re
text = "Contact email: john.doe@example.com"
pattern = r"(\w+)\.(\w+)@(\w+)\.(\w+)"
match = re.search(pattern, text)
if match:
username = match.group(1)
lastname = match.group(2)
domain = match.group(3)
tld = match.group(4)
print(f"Username: {username}")
print(f"Lastname: {lastname}")
print(f"Domain: {domain}")
print(f"TLD: {tld}")
else:
print("No match found.")
파일을 저장합니다.
이제 python 명령을 사용하여 스크립트를 실행합니다.
python basic_capture.py
다음 출력을 볼 수 있습니다.
Username: john
Lastname: doe
Domain: example
TLD: com
이 출력은 스크립트가 캡처 그룹을 사용하여 이메일 주소의 다른 부분을 성공적으로 추출했음을 보여줍니다.
groups() 메서드를 사용하여 튜플로 모든 캡처된 그룹에 액세스할 수도 있습니다. basic_capture.py 파일을 수정하여 if match: 블록 뒤에 다음 줄을 포함합니다.
all_groups = match.groups()
print(f"All groups: {all_groups}")
파일을 저장하고 스크립트를 다시 실행합니다.
python basic_capture.py
이제 출력에는 모든 캡처된 그룹의 튜플이 포함됩니다.
Username: john
Lastname: doe
Domain: example
TLD: com
All groups: ('john', 'doe', 'example', 'com')
이것은 기본 캡처 그룹을 사용하고 캡처된 데이터에 액세스하는 방법을 보여줍니다.
명명된 캡처 그룹은 각 그룹에 이름을 할당하여 캡처된 데이터에 더 읽기 쉬운 방식으로 액세스할 수 있도록 합니다. 명명된 캡처 그룹의 구문은 (?P<name>...)입니다.
명명된 캡처 그룹을 시연하기 위해 새로운 Python 스크립트를 만들어 보겠습니다.
~/project 디렉토리에 named_capture.py라는 새 파일을 만듭니다.
touch ~/project/named_capture.py
WebIDE 편집기에서 named_capture.py를 열고 다음 Python 코드를 추가합니다.
import re
text = "Product: Laptop, Price: $999.99"
pattern = r"Product: (?P<product>\w+), Price: \$(?P<price>\d+\.\d+)"
match = re.search(pattern, text)
if match:
product = match.group('product')
price = match.group('price')
print(f"Product: {product}, Price: ${price}")
else:
print("No match found.")
파일을 저장합니다.
python 명령을 사용하여 스크립트를 실행합니다.
python ~/project/named_capture.py
다음 출력을 볼 수 있습니다.
Product: Laptop, Price: $999.99
이 출력은 스크립트가 명명된 캡처 그룹을 사용하여 제품 이름과 가격을 성공적으로 추출했음을 보여줍니다. group() 메서드에서 그룹 이름을 키로 사용하여 캡처된 데이터에 액세스할 수 있습니다.
명명된 캡처 그룹은 특히 많은 캡처 그룹이 있는 복잡한 패턴의 경우, 정규 표현식 패턴과 후속 코드를 더 이해하기 쉽게 만듭니다.
캡처 그룹은 로그 파일, URL 및 구조화된 데이터와 같은 다양한 텍스트 형식에서 데이터를 추출하는 데 널리 사용됩니다.
캡처 그룹을 사용하여 로그 항목을 구문 분석하는 스크립트를 만들어 보겠습니다.
~/project 디렉토리에 log_parser.py라는 새 파일을 만듭니다.
touch ~/project/log_parser.py
WebIDE 편집기에서 log_parser.py를 열고 다음 Python 코드를 추가합니다.
import re
log_entry = '2023-06-15 14:30:45 [ERROR] Database connection failed'
pattern = r'(\d{4}-\d{2}-\d{2}) (\d{2}:\d{2}:\d{2}) \[(\w+)\] (.+)'
match = re.match(pattern, log_entry)
if match:
date = match.group(1)
time = match.group(2)
log_level = match.group(3)
message = match.group(4)
print(f"Date: {date}")
print(f"Time: {time}")
print(f"Level: {log_level}")
print(f"Message: {message}")
else:
print("No match found.")
파일을 저장합니다.
python 명령을 사용하여 스크립트를 실행합니다.
python ~/project/log_parser.py
다음 출력을 볼 수 있습니다.
Date: 2023-06-15
Time: 14:30:45
Level: ERROR
Message: Database connection failed
이 스크립트는 캡처 그룹을 사용하여 로그 항목을 성공적으로 구문 분석하고 날짜, 시간, 로그 레벨 및 메시지를 추출했습니다.
또 다른 일반적인 사용 사례는 URL 에서 정보를 추출하는 것입니다. ~/project 디렉토리에 url_parser.py라는 새 파일을 만듭니다.
touch ~/project/url_parser.py
url_parser.py를 열고 다음 코드를 추가합니다.
import re
def parse_url(url):
pattern = r'(https?://)?([^/]+)(/.*)?'
match = re.match(pattern, url)
if match:
protocol = match.group(1) or 'http://'
domain = match.group(2)
path = match.group(3) or '/'
return {
'protocol': protocol,
'domain': domain,
'path': path
}
return None
## Example usage
url = 'https://www.example.com/path/to/page'
parsed_url = parse_url(url)
if parsed_url:
print(f"Protocol: {parsed_url['protocol']}")
print(f"Domain: {parsed_url['domain']}")
print(f"Path: {parsed_url['path']}")
else:
print("Invalid URL format.")
url_no_protocol = 'example.org/another/path'
parsed_url_no_protocol = parse_url(url_no_protocol)
if parsed_url_no_protocol:
print(f"\nProtocol: {parsed_url_no_protocol['protocol']}")
print(f"Domain: {parsed_url_no_protocol['domain']}")
print(f"Path: {parsed_url_no_protocol['path']}")
else:
print("\nInvalid URL format.")
파일을 저장합니다.
스크립트를 실행합니다.
python ~/project/url_parser.py
출력은 URL 의 구문 분석된 구성 요소를 표시합니다.
Protocol: https://
Domain: www.example.com
Path: /path/to/page
Protocol: http://
Domain: example.org
Path: /another/path
이러한 예제는 텍스트에서 구조화된 데이터를 추출하는 데 캡처 그룹의 실용적인 적용을 보여줍니다.
기본 캡처 그룹 외에도 Python 정규 표현식은 중첩 캡처 그룹, 비 캡처 그룹 및 lookarounds 와 같은 더 고급 기능을 제공합니다.
캡처 그룹은 더 세분화된 정보를 추출하기 위해 다른 캡처 그룹 내에 중첩될 수 있습니다.
~/project 디렉토리에 nested_capture.py라는 새 파일을 만듭니다.
touch ~/project/nested_capture.py
nested_capture.py를 열고 다음 코드를 추가합니다.
import re
def parse_complex_data(text):
pattern = r'((\w+)\s(\w+))\s\[(\d+)\]'
match = re.match(pattern, text)
if match:
full_name = match.group(1)
first_name = match.group(2)
last_name = match.group(3)
id_number = match.group(4)
return {
'full_name': full_name,
'first_name': first_name,
'last_name': last_name,
'id': id_number
}
return None
text = 'John Doe [12345]'
result = parse_complex_data(text)
if result:
print(f"Full Name: {result['full_name']}")
print(f"First Name: {result['first_name']}")
print(f"Last Name: {result['last_name']}")
print(f"ID: {result['id']}")
else:
print("No match found.")
파일을 저장합니다.
스크립트를 실행합니다.
python ~/project/nested_capture.py
출력은 전체 이름과 해당 구성 요소를 포함하여 추출된 데이터를 표시합니다.
Full Name: John Doe
First Name: John
Last Name: Doe
ID: 12345
여기서 ((\w+)\s(\w+))는 중첩 캡처 그룹입니다. group(1)은 전체 "John Doe"를 캡처하고, group(2)는 "John"을 캡처하며, group(3)은 "Doe"를 캡처합니다. group(4)는 ID 를 캡처합니다.
때로는 수량자 (quantifier) 또는 대안을 적용하기 위해 패턴의 일부를 그룹화해야 하지만 내용을 캡처할 필요가 없는 경우가 있습니다. 비 캡처 그룹 (?:...)은 이러한 목적으로 사용됩니다.
~/project 디렉토리에 non_capturing.py라는 새 파일을 만듭니다.
touch ~/project/non_capturing.py
non_capturing.py를 열고 다음 코드를 추가합니다.
import re
def extract_domain_info(url):
## (?:) creates a non-capturing group
pattern = r'https?://(?:www\.)?([^/]+)'
match = re.match(pattern, url)
if match:
domain = match.group(1) ## Only the domain is captured
return domain
return None
url1 = 'https://www.example.com/path'
domain1 = extract_domain_info(url1)
print(f"Domain from '{url1}': {domain1}")
url2 = 'http://example.org/another/path'
domain2 = extract_domain_info(url2)
print(f"Domain from '{url2}': {domain2}")
파일을 저장합니다.
스크립트를 실행합니다.
python ~/project/non_capturing.py
출력은 추출된 도메인 이름을 표시합니다.
Domain from 'https://www.example.com/path': example.com
Domain from 'http://example.org/another/path': example.org
이 예제에서 (?:www\.)?는 "www."가 있으면 일치하지만 캡처하지 않으므로 group(1)은 직접 도메인 이름을 캡처합니다.
비 캡처 그룹을 사용하면 성능을 약간 향상시키고 더 큰 패턴의 특정 부분만 캡처해야 할 때 캡처된 그룹 인덱스를 더 깔끔하게 유지할 수 있습니다.
이 랩에서는 Python 에서 정규 표현식 캡처 그룹을 사용하는 방법을 배웠습니다. 기본적인 캡처 그룹으로 시작하여 가독성을 높이기 위해 명명된 캡처 그룹을 탐구했습니다. 또한 로그 파일 및 URL 구문 분석과 같은 실용적인 데이터 추출 작업에 캡처 그룹을 사용하는 연습을 했습니다. 마지막으로 중첩 및 비 캡처 그룹과 같은 고급 기술을 소개했습니다. 이러한 개념을 마스터함으로써 Python 에서 정규 표현식을 사용하여 텍스트 데이터의 특정 부분을 효과적으로 추출하고 조작할 수 있습니다.