본문 바로가기
GD's IT Lectures : 기초부터 시리즈/파이썬(Python) 기초부터 ~

[파이썬(PYTHON) : 중급] 고급 문자열 처리

by GDNGY 2023. 5. 7.

1. 고급 문자열 처리

고급 문자열 처리에서는 복잡한 문자열 조작 및 검색 작업을 수행하기 위해 정규 표현식을 다룹니다. 정규 표현식을 사용하여 텍스트에서 패턴을 검색, 대체, 추출하는 방법을 학습하게 됩니다. 또한 유니코드 문자열 처리를 통해 다양한 언어 및 문자 시스템을 다루는 방법에 대해 알아봅니다.

 

1.1 정규 표현식 활용하기

1.1.1 기본 정규 표현식 문법

  • 정규 표현식은 문자열에서 특정 패턴을 찾거나 검증하기 위한 문법입니다.
  • 파이썬에서는 re 모듈을 사용하여 정규 표현식을 처리할 수 있습니다.
import re

 

기본 정규 표현식 문법
  • .: 임의의 한 문자
  • *: 앞의 문자가 0번 이상 반복
  • +: 앞의 문자가 1번 이상 반복
  • ?: 앞의 문자가 0 또는 1번 등장
  • {n}: 앞의 문자가 n번 반복
  • {n,}: 앞의 문자가 n번 이상 반복
  • {,m}: 앞의 문자가 m번 이하 반복
  • {n,m}: 앞의 문자가 n번 이상 m번 이하 반복
  • []: 문자 클래스(대괄호 안의 문자 중 하나와 일치)
  • [^]: 부정 문자 클래스(대괄호 안의 문자와 일치하지 않는 것)
  • |: OR 연산자
  • (): 그룹화
  • \: 이스케이프 문자
  • ^: 문자열의 시작
  • $: 문자열의 끝
  • \d: 숫자
  • \D: 숫자가 아닌 문자
  • \w: 문자, 숫자, 밑줄
  • \W: 문자, 숫자, 밑줄이 아닌 문자
  • \s: 공백 문자
  • \S: 공백 문자가 아닌 문자

 

1.1.2 정규 표현식을 이용한 문자열 검색과 치환

  • re.search(): 문자열에서 정규 표현식과 일치하는 부분을 찾습니다. 일치하는 부분이 있으면 match 객체를 반환하고, 없으면 None을 반환합니다.
  • re.findall(): 문자열에서 정규 표현식과 일치하는 모든 부분을 찾아 리스트로 반환합니다.
  • re.finditer(): 문자열에서 정규 표현식과 일치하는 모든 부분을 찾아 반복 가능한 match 객체를 반환합니다.
  • re.sub(): 문자열에서 정규 표현식과 일치하는 부분을 다른 문자열로 치환합니다.
import re

text = "Python is fun, isn't it?"
pattern = r'\w+'

# Search
result = re.search(pattern, text)
print(result.group())  # Output: 'Python'

# Find all
result = re.findall(pattern, text)
print(result)  # Output: ['Python', 'is', 'fun', 'isn', 't', 'it']

# Find iter
result = re.finditer(pattern, text)
for match in result:
    print(match.group())  
    # Output: 
    # 'Python'
    # 'is'
    # 'fun'
    # 'isn'
    # 't'
    # 'it'

# Sub
result = re.sub(pattern, 'word', text)
print(result)  # Output: 'word word word, word word word?'

 

1.1.3 정규 표현식을 이용한 문자열 분리 및 추출

  • re.split(): 정규 표현식을 기준으로 문자열을 분리합니다.
  • re.compile(): 여러 작업에 사용할 정규 표현식 패턴을 미리 컴파일하여 재사용 가능하게 합니다.
import re

text = "Python is fun, isn't it?"
pattern = r'\W+'

# Split
result = re.split(pattern, text)
print(result)  # Output: ['Python', 'is', 'fun', 'isn', 't', 'it', '']

# Compile
compiled_pattern = re.compile(pattern)

result = compiled_pattern.split(text)
print(result)  # Output: ['Python', 'is', 'fun', 'isn', 't', 'it', '']

 

1.1.4 정규 표현식을 이용한 문자열 유효성 검사

  • 이메일 주소 유효성 검사 예제
import re

email_pattern = r'^[\w\.-]+@[\w\.-]+\.\w+$'

def is_valid_email(email):
    return re.search(email_pattern, email)

print(is_valid_email('john@example.com'))  # Output: <re.Match object; span=(0, 17), match='john@example.com'>
print(is_valid_email('john@example'))      # Output: None

 

1.2 문자열 포맷팅

1.2.1 문자열 포맷팅 기본 문법

    • 문자열 내에서 중괄호 {}를 사용하여 변수를 삽입할 수 있는 위치를 표시합니다.
name = "John"
age = 30
result = "My name is {} and I am {} years old.".format(name, age)
print(result)  # Output: 'My name is John and I am 30 years old.'

 

1.2.2 f-string 포맷팅

  • f-string은 문자열 앞에 f 또는 F를 붙여 사용합니다. 중괄호 {} 안에 변수를 직접 사용할 수 있습니다.
name = "John"
age = 30
result = f"My name is {name} and I am {age} years old."
print(result)  # Output: 'My name is John and I am 30 years old.'

 

1.2.3 str.format() 메서드를 이용한 포맷팅

  • 중괄호 {}에 인덱스를 사용하여 순서를 지정할 수 있습니다.
name = "John"
age = 30
result = "My name is {0} and I am {1} years old.".format(name, age)
print(result)  # Output: 'My name is John and I am 30 years old.'

 

1.2.4 템플릿 문자열(Template Strings)을 이용한 포맷팅

  • string 모듈의 Template 클래스를 사용하여 문자열 템플릿을 생성하고, substitute() 또는 safe_substitute() 메서드를 사용하여 변수를 삽입할 수 있습니다.
from string import Template

name = "John"
age = 30
template = Template("My name is $name and I am $age years old.")
result = template.substitute(name=name, age=age)
print(result)  # Output: 'My name is John and I am 30 years old.'

 

1.3 유니코드 문자열 다루기

1.3.1 유니코드 문자열과 인코딩

  • 파이썬 3부터는 모든 문자열이 유니코드 문자열입니다.
  • 인코딩은 유니코드 문자열을 바이트열로 변환하는 과정입니다. 대표적인 인코딩 방식에는 UTF-8이 있습니다.
  • 디코딩은 바이트열을 유니코드 문자열로 변환하는 과정입니다.
# Encoding
text = "안녕하세요"
encoded_text = text.encode('utf-8')
print(encoded_text)  # Output: b'\xec\x95\x88\xeb\x85\x95\xed\x95\x98\xec\x84\xb8\xec\x9a\x94'

# Decoding
decoded_text = encoded_text.decode('utf-8')
print(decoded_text)  # Output: '안녕하세요'

 

1.3.2 유니코드 문자열의 길이와 슬라이싱

  • 유니코드 문자열의 길이는 len() 함수를 사용하여 구할 수 있습니다.
  • 유니코드 문자열에서 일부 문자를 추출하려면 슬라이싱을 사용합니다.
text = "안녕하세요"
length = len(text)
print(length)  # Output: 5

sliced_text = text[1:4]
print(sliced_text)  # Output: '녕하세'

 

1.3.3 유니코드 문자열의 정렬과 검색

  • 문자열의 정렬은 str.ljust(), str.rjust(), str.center() 메서드를 사용하여 할 수 있습니다.
  • 문자열에서 특정 문자나 문자열을 찾을 때는 str.find()나 str.index() 메서드를 사용합니다.
text = "안녕하세요"

# Align left
print(text.ljust(10))  # Output: '안녕하세요     '

# Align right
print(text.rjust(10))  # Output: '     안녕하세요'

# Center
print(text.center(10))  # Output: '  안녕하세요   '

# Find
print(text.find("하"))    # Output: 2
print(text.find("헬로"))  # Output: -1

# Index
print(text.index("하"))    # Output: 2
print(text.index("헬로"))  # Raises ValueError

 

1.3.4 유니코드 문자열의 대소문자 변환과 비교

  • 유니코드 문자열의 대문자와 소문자를 변환하려면 str.upper()와 str.lower() 메서드를 사용합니다.
  • 유니코드 문자열을 비교할 때는 대소문자를 무시하려면 str.casefold() 메서드를 사용하여 비교할 수 있습니다.
text = "Hello, World!"

# Upper
print(text.upper())  # Output: 'HELLO, WORLD!'

# Lower
print(text.lower())  # Output: 'hello, world!'

# Case-insensitive comparison
text1 = "Hello, World!"
text2 = "hello, world!"
print(text1.casefold() == text2.casefold())  # Output: True

 

1.4 문자열 압축과 암호화

1.4.1 문자열 압축 기법

  • zlib, gzip, bz2, lzma와 같은 파이썬 내장 모듈을 사용하여 문자열을 압축할 수 있습니다.
import zlib

text = b"Hello, World! Hello, World!"
compressed_text = zlib.compress(text)
print(compressed_text)  # Output: b'x\x9c\xcbH\xcd\xc9\xc9W(\xcf/\xcaIQ\xcc \x82\r\x00\xbd[\x11\xf5'

decompressed_text = zlib.decompress(compressed_text)
print(decompressed_text)  # Output: b'Hello, World! Hello, World!'

 

1.4.2 문자열 암호화 기법

  • hashlib, hmac 모듈을 사용하여 해시 함수를 이용한 암호화를 할 수 있습니다.
  • 대칭키 암호화는 cryptography, pycrypto와 같은 외부 라이브러리를 사용하여 수행할 수 있습니다.

 

1.4.3 문자열 복호화 기법

  • 암호화된 문자열을 원래 문자열로 되돌리는 복호화 과정입니다. 복호화 방법은 사용된 암호화 기법에 따라 다릅니다.
  • 대칭키 암호화의 경우, 암호화에 사용된 키와 알고리즘을 이용하여 복호화를 수행합니다.

 

1.4.4 암호화와 복호화를 위한 파이썬 라이브러리 사용하기

  • cryptography 라이브러리를 사용한 대칭키 암호화 예제 (Fernet)
from cryptography.fernet import Fernet

# Key generation
key = Fernet.generate_key()
cipher_suite = Fernet(key)

# Encryption
text = b"Hello, World!"
encrypted_text = cipher_suite.encrypt(text)
print(encrypted_text)

# Decryption
decrypted_text = cipher_suite.decrypt(encrypted_text)
print(decrypted_text)  # Output: b'Hello, World!'

 

반응형

댓글