자동배포봇 프로젝트를 진행하면서 문자열처리를 해야하는 경우가 많았는데 정리해본다.
정규표현식(re)
1. re.sub(pattern="정규식", repl="치환문자", string="문자열", count=숫자)
문자열에서 정규식으로 선택된 부분을 count개 만큼 문자열 앞에서 부터 치환문자로 바꿔준다. count의 default=1
line = "제목: 푸딩테스트"
title = re.sub(" *제목 *:*", "", line) # 정규식으로 제목 들어간 부분을 삭제
line = "제목: 푸딩테스트 제목 제목"
print(re.sub(" *제목 *:*", "", line, count=2)) # 앞에서부터 발견되는 문자열 2개만 치환.
# 결과: 푸딩테스트제목
#여러 라인 처리
lines = """\
제목: 푸딩테스트1
제목: 푸딩테스트2
제목 : 푸딩테스트3
"""
titles = re.sub(" *제목 *:*", "", lines, flags=re.MULTILINE)
혹은 complie을 써서 sub를 표현할 수도 있다.
re.compile(" *제목 *:*").sub("", line)
2. re.subn(pattern="정규식", repl="치환문자", string="문자열", count=숫자)
re.sub 결과값에 치환된 문자 갯수를 추가해서 튜플로 반환
line = "제목: 푸딩테스트 제목 제목"
print(re.subn(" *제목 *:*", "", line, count=2)) # 정규식으로 제목 들어간 부분을 삭제
#(' 푸딩테스트제목', 2)
정규식으로 선택된 문자열 다시 사용하기 : "\g<0>" 이용
line = "제목: 젤리 & 젤리 & 젤리"
print(re.subn("젤리", "사과 \g<0>", line, count=2)) # 정규식으로 제목 들어간 부분을 삭제
# ('제목: 사과 젤리 & 사과 젤리 & 젤리', 2)
[참조]
3. re.split("정규식", 문자열)
정규식을 기준으로 문자열을 분리해서 리스트로 반환
line = "사과 젤리 & 메로나 젤리 & 초코 젤리"
print(re.split(" *젤리 &* *", line))
# ['사과', '메로나', '초코 젤리']
[참조]
4. re.match("정규식",문자열) & re.search("정규식",문자열)
문자열에서 정규식에 해당하는 문자열이 있는지 확인하는 함수들. match는 문자열 처음부터 정규식과 매치되는 것이 있는지 확인하고 search는 꼭 문자열 처음부터 일치하지 않아도 된다. 일치하는 문자열이 없을 때는 None을 반환 [참조]
같이 쓰이는 함수
- group(): 매치 문자열 반환
- start(): 매치 문자열 시작 위치
- end(): 매치 문자열 끝 위치
- span() : 매치 문자열 시작, 끝 위치 튜플로 반환
5. re.findall("정규식", 문자열) & re.finditer
문자열에서 패턴과 일치하는 부분을 리스트로 반환한다. re.finditer같은 경우는 matchObj를 iterable object로 반환.
line = "젤리 10개 & 메로나 5개"
# 두 자리 이하로 이루어진 숫자 모두 찾아내시오
print(re.findall("[0-9]{1,2}", line))
print(re.compile("[0-9]{1,2}").findall(line))
# 결과: ['10', '5']
정규식은 이것말고도 쓸만한게 많다. 이곳[참조]에 정규표현식에 대해 여러 글에 걸쳐 자세하게 설명되어 있다.
or 정규식 관련 위키독스
Raw string
string 앞에 r을 붙여준다. raw string에서는 escape문(\가 앞에 붙는 문자들. ex. \b, \n) 이 적용이 안 되고 문자 그대로 출력된다.
print("프린트 \b") # "프린트" 출력
print(r"프린트 \b") # "프린트 \b" 이 출력됨
파일 확장자(file extension) 확인하기
1. endswith('특정문자열')
string이 특정문자열로 끝나는지 확인해주는 함수
if m.endswith('.mp3'):
...
elif m.endswith('.flac'):
...
# 여러 개중 하나 만족하는지도 검사할 수 있음
'./my_image.JPG'.lower().endswith(('.png', '.jpg', '.jpeg'))
[참조]
2. os.path.splitext("파일경로")
파일경로에서 파일 extension(확장자)와 나머지 문자열을 tuple로 리턴.
import os
filepaths = ["/folder/soundfile.mp3", "folder1/folder/soundfile.flac"]
for fp in filepaths:
# Split the extension from the path and normalise it to lowercase.
ext = os.path.splitext(fp)[-1].lower()
print(os.path.splitext(fp))
'''
# 출력결과
('/folder/soundfile', '.mp3')
('folder1/folder/soundfile', '.flac')
'''
[참조]
3. pathlib.Path("파일경로").suffix
파일에서 확장자만 리턴
from pathlib import Path
print(Path('my_file.mp3').suffix)
# 출력결과
# '.mp3'
[참조]
4. fnmatch.fnmatch("파일경로")
import fnmatch
import os
for file in os.listdir('.'): # 현재 위치의 파일리스트를 가져온다
if fnmatch.fnmatch(file, '*.txt'):
print(file)
[참조]