문자열 처리 함수가 많네요! 일단은 한번에 알아보도록 할게요! 혹시 너무 많으면 2탄으로 바꾸겠습니다... ㅎㅎ
그래도 글 위에 목차를 누르면 궁금한 함수를 바로 볼 수 있으니 괜찮겠죠? ㅎㅎ
그리고 목차로 다시 가고 싶으면 오른쪽 아래 위로가기 버튼 누르면 바로 올라갑니다!

문자열 전처리
파이썬으로 데이터 분석, 웹 크롤링, 혹은 인공지능(NLP) 모델을 다루다 보면 문자열(String) 전처리는 피할 수 없는 필수 관문입니다. 수집된 날것의 데이터(Raw Data)는 불필요한 기호나 공백이 섞여 있는 경우가 많기 때문입니다.
1. 문자열 분해하기: split()
문자열을 특정 구분자(기준 문자열)를 기반으로 쪼개어 리스트(List) 형태로 반환하는 함수입니다. 수집한 텍스트나 로그 데이터, URL 등을 분해할 때 매우 자주 사용됩니다.
- 특징: 구분자를 지정하지 않으면 띄어쓰기(공백)나 엔터(줄바꿈)를 기준으로 자동 분리됩니다.
실습 예제: URL 데이터 파싱(ETL) 복잡한 뉴스 URL에서 기사 번호나 특정 코드 값만 추출해야 하는 상황을 가정해 보겠습니다.
# 더미 데이터 (뉴스 URL)
url = 'https://www.kookje.co.kr/news2011/asp/newsbody.asp/20260702.9909900054?code=0200&key=8&uid=ab&aid=7868'
# 1. URL과 파라미터 분리하기 ('?' 기준)
base_url_part = url.split('?')[0]
query_part = url.split('?')[1]
# 2. 파라미터 값들 추출하기
# 파라미터 뭉치를 '&'로 쪼갠 뒤, 각각을 다시 '='로 쪼개어 값(인덱스 1)만 가져옵니다.
code_val = query_part.split('&')[0].split('=')[1] # 0200
key_val = query_part.split('&')[1].split('=')[1] # 8
uid_val = query_part.split('&')[2].split('=')[1] # ab
aid_val = query_part.split('&')[3].split('=')[1] # 7868
# 3. URL 경로의 마지막 기사 번호 추출하기
news_no = base_url_part.split('/')[-1] # 20260702.9909900054
print(f"기사번호: {news_no}, code: {code_val}, key: {key_val}")
💡 추가 팁 (Pro-tip): 단순한 문자열 분해는 split()이 훌륭하지만, 위와 같이 복잡한 URL 파라미터를 다룰 때는 파이썬 내장 라이브러리인 urllib.parse 모듈의 parse_qs를 사용하는 것이 훨씬 안전하고 파이썬다운(Pythonic) 방법입니다!
from urllib.parse import urlparse, parse_qs
# 1. 아까와 동일한 더미 데이터 (뉴스 URL)
url = 'https://www.kookje.co.kr/news2011/asp/newsbody.asp/20260702.9909900054?code=0200&key=8&uid=ab&aid=7868'
# 2. urlparse: URL을 의미 있는 조각(scheme, netloc, path, query 등)으로 분해합니다.
parsed_url = urlparse(url)
print("추출된 쿼리 스트링:", parsed_url.query)
# 결과: code=0200&key=8&uid=ab&aid=7868
# 3. parse_qs: 쿼리 스트링을 파이썬 딕셔너리(Dict) 형태로 변환합니다.
# 주의: 하나의 키에 여러 값이 올 수 있는 URL 특성상, 값들이 리스트(List) 형태로 묶여서 반환됩니다.
params = parse_qs(parsed_url.query)
print("딕셔너리로 변환된 파라미터:", params)
# 결과: {'code': ['0200'], 'key': ['8'], 'uid': ['ab'], 'aid': ['7868']}
# 4. 딕셔너리에서 원하는 값만 깔끔하게 추출 (리스트의 첫 번째 값 [0]을 가져옵니다)
# 딕셔너리의 get() 메서드를 사용하면 파라미터가 누락되었을 때의 에러도 방지할 수 있습니다.
code_val = params.get('code', [''])[0] # 'code'가 없으면 빈 문자열 반환
key_val = params.get('key', [''])[0]
uid_val = params.get('uid', [''])[0]
# URL 경로(path)에서 마지막 기사 번호를 추출하는 것은 기존 split()을 활용하는 것이 깔끔합니다.
news_no = parsed_url.path.split('/')[-1]
print(f"기사번호: {news_no}, code: {code_val}, key: {key_val}")
# 결과: 기사번호: 20260702.9909900054, code: 0200, key: 8
2. 문자열 조립하기: join()
split()의 반대 역할을 하는 함수입니다. 리스트나 튜플 같은 컬렉션 계열의 문자열 멤버들을 특정 구분자를 이용해 하나의 문자열로 합쳐줍니다.
- 활용처: 자연어 처리(NLP)에서 형태소 단위로 쪼개진 N개의 조각을 다시 하나의 말뭉치(Corpus) 문장으로 구성할 때 유용합니다.
# 더미 데이터 (문자들이 담긴 리스트)
data = list("helloworld")
print(data) # ['h', 'e', 'l', 'l', 'o', 'w', 'o', 'r', 'l', 'd']
# 문자열 조립하기
print('-'.join(data)) # h-e-l-l-o-w-o-r-l-d
print(' '.join(data)) # h e l l o w o r l d (띄어쓰기로 연결)
print(''.join(data)) # helloworld (구분자 없이 바로 연결)
3. 대소문자 일괄 변환: lower(), upper()
알파벳 문자열의 대소문자를 일괄적으로 변경합니다.
- 활용처:
- 사용자 입력 예외 처리: 패키지 설치 시 yes, Y, Yes 등 다양한 입력을 모두 lower()로 받아 y인지 검사하여 사용자 편의성을 높일 수 있습니다.
- 데이터 정규화: 아이디 중복 검사나 자연어 처리 과정에서 대소문자가 다르면 컴퓨터는 다른 단어로 인식하므로, 통상적으로 모두 소문자로 통일하는 전처리를 진행합니다.
data = 'ab CD 가나 12 !@'
print(data.lower()) # ab cd 가나 12 !@ (모두 소문자로)
print(data.upper()) # AB CD 가나 12 !@ (모두 대문자로)
💡 추가 팁: 첫 글자만 대문자로 바꾸고 싶다면 capitalize()를, 각 단어의 첫 글자만 대문자로 바꾸고 싶다면 title() 함수를 사용할 수 있습니다.
4. 불필요한 공백 제거: strip(), lstrip(), rstrip()
웹 크롤링이나 사용자의 키보드 입력 시 의도치 않게 들어간 양 끝의 공백(스페이스바, 엔터, 탭 등)은 데이터 분석의 노이즈가 됩니다. 이를 제거하는 함수입니다.
- lstrip(): 문자열 왼쪽(Left) 공백 제거
- rstrip(): 문자열 오른쪽(Right) 공백 제거
- strip(): 문자열 양쪽 공백 모두 제거 (가장 많이 사용됨)
# 띄어쓰기가 포함된 데이터 (시각화를 위해 대괄호 [] 로 감싸서 출력)
data = ' ab cd '
print('[' + data + ']') # [ ab cd ]
print('[' + data.lstrip() + ']') # [ab cd ]
print('[' + data.rstrip() + ']') # [ ab cd]
print('[' + data.strip() + ']') # [ab cd]
⚠️ 주의할 점: strip() 계열 함수는 가장자리(경계)에 있는 공백만 제거합니다. 문자열 내부(가운데)에 있는 공백을 제거하려면 data.replace(' ', '') 처럼 단순 대체를 사용하거나, 패턴이 복잡하다면 정규표현식(re 모듈)을 사용해야 합니다.
import re
# 탭(\t), 줄바꿈(\n), 여러 개의 스페이스바가 혼재된 문자열
data = ' ab cd\t ef \n gh '
# 1. 단순 replace() 사용의 한계
# 명시적으로 스페이스바(' ')만 빈 문자열('')로 제거하며, 탭과 줄바꿈은 그대로 남습니다.
result_replace = data.replace(' ', '')
print(f"replace 적용: [{result_replace}]")
# 출력: [abcd ef
# gh]
# 2. re.sub()를 이용한 모든 공백 완벽 제거
# \s+ 패턴을 통해 탭, 줄바꿈, 스페이스바를 모두 찾아 빈 문자열('')로 치환합니다.
result_remove_all = re.sub(r'\s+', '', data)
print(f"re.sub 전체 제거: [{result_remove_all}]")
# 출력: [abcdefgh]
# 3. 실무 활용: 다중 공백 정규화 (압축)
# 내부의 불규칙한 공백들을 단 하나의 스페이스바(' ')로 통일하여 데이터의 가독성을 높입니다.
# 통상적으로 양 끝에 남은 공백은 마지막에 strip()을 호출하여 제거합니다.
result_normalize = re.sub(r'\s+', ' ', data).strip()
print(f"re.sub 공백 정규화: [{result_normalize}]")
# 출력: [ab cd ef gh]
5. 문자열 탐색 및 필터링: find(), index(), in 연산자
문자열 내부에 내가 원하는 특정 단어가 포함되어 있는지 검사하거나, 그 위치를 찾아냅니다.
1) 위치 찾기 (find vs index)
두 함수 모두 찾는 문자열의 첫 번째 인덱스 번호를 반환하지만, 찾는 문자열이 없을 때의 반응이 다릅니다.
data = 'abcdefg'
# 찾는 문자열이 있을 때
print(data.find('cd')) # 2 (인덱스 반환)
print(data.index('cd')) # 2 (인덱스 반환)
# 찾는 문자열이 없을 때
print(data.find('z')) # -1 을 반환 (프로그램이 멈추지 않음)
# print(data.index('z')) # ValueError 발생! (프로그램이 멈춤)
실무에서는 에러로 인한 프로그램 중단을 막기 위해 보통 find()를 더 선호합니다. (선생님은 그냥 무조건 find 를 쓰라고 하셨습니다.)
2) 시작과 끝 확인 (startswith, endswith)
조건문(if)과 결합하여 데이터를 필터링할 때 강력한 기능입니다. 결과는 True 또는 False로 반환됩니다.
# 특정 단어로 시작하는지?
print(data.startswith('abc')) # True
# 특정 단어로 끝나는지? (파일 확장자 검사에 매우 유용!)
filename = "report.csv"
print(filename.endswith('.csv')) # True
3) 단순 존재 여부만 체크 (in 연산자)
위치가 궁금한 것이 아니라, 단순히 '포함되어 있는지'만 알고 싶다면 파이썬의 in 연산자를 사용하는 것이 가장 빠르고 직관적입니다.
print('cd' in data) # True
print('z' in data) # False
6. 문자열 일괄 변경 및 대체: replace()
데이터 전처리(Preprocessing) 과정에서 가장 빈번하게 발생하는 작업 중 하나는 특정 문자나 기호, 혹은 오타를 일괄적으로 변경하는 것입니다. 파이썬에서는 replace() 함수를 사용해 문자열 내에서 지정한 패턴을 찾아 다른 문자로 손쉽게 바꿀 수 있습니다.
- 특징: 문자열 내에 존재하는 모든 매칭 패턴을 찾아내어 일괄적으로 변경합니다. (가장 먼저 발견된 것 하나만 바꾸는 것이 아닙니다.)
# 1. 특정 문자를 기호로 일괄 변경하기
# 'l' 문자를 찾아 모두 '@'로 변경합니다.
result1 = 'helloworld'.replace('l', '@')
print(result1) # 출력: he@@owor@d
# 2. 문자열 내부의 모든 공백 제거하기
# 앞서 배운 strip() 함수는 가장자리의 공백만 제거하지만,
# replace()를 이용해 공백(' ')을 빈 문자열('')로 대체하면 내부의 모든 공백을 제거할 수 있습니다.
result2 = 'pie n e app le'.replace(' ', '')
print(result2) # 출력: pineapple
💡 데이터 분석(Pandas) 실무 확장 팁
현재 다루고 있는 기본 파이썬 문자열 replace() 함수는 단 하나의 문자열 객체에만 적용됩니다.
하지만 향후 데이터 분석 라이브러리인 Pandas를 활용해 수만 행의 엑셀 표(DataFrame) 데이터를 다루게 된다면, 특정 열(Column) 전체의 문자열을 한 번에 바꿀 때 pandas.DataFrame.str.replace() 형태의 확장된 문법을 사용하게 된답니다.
기본적인 작동 원리는 파이썬 고유의 replace()와 완벽히 동일하다고 하고, 지금 이 개념을 정확히 이해해 두시면 대용량 데이터 전처리도 쉽게 접근하실 수 있다고 합니다!
오늘의 한 마디
왜 이렇게 다들 조급한지 모르겠다. 취직, 결혼, 집 사기.... 너무 숙제처럼 여겨서 무조건 해내야하는 느낌이다. 그냥 자연스럽게 내가 갈 길을 가면 언젠가 도착해있지 않을까? 조급하게 생각하지 않으면서 노력한다면 저것들을 다 이뤄내지 않을까 생각이 든다. 진정 자신이 무엇을 원하는지 부터 생각하면서 진중하게 신중하게 하면 좋을 것 같다는 생각이 든다.
아! 스트레스를 받아서 저렇게 쓰는 것은 아니다 ㅋㅋㅋ
'코딩 개발 > Python' 카테고리의 다른 글
| Python - 딕셔너리 Dictionary (데이터 추가 및 수정, 인덱싱, get(), keys(), values(), items(), del, clear()) (0) | 2026.07.10 |
|---|---|
| Python - 문자열 포매팅 (%, format, f-string) (0) | 2026.07.08 |
| Python - 데이터 추출 슬라이싱(Slicing) - 변수명[시작 인덱스 : 끝 인덱스 : step(간격, 기본값1, 생략가능) (0) | 2026.07.06 |
| Python - 문자열 추출(인덱싱) (0) | 2026.07.05 |
| Python - 단일 데이터형 (수치형) (0) | 2026.07.03 |