목차
정규표현식
•
특정 패턴을 이용해 문자열을 처리하는 방법
•
호불호가 있지만 강사님은 필요시에만 사용하는 것이 좋다고 생각함
◦
작성하면서 실수하기도 쉽고, 이해하는데도 가독성이 떨어짐
◦
문자열 함수를 쓰는 것이 가독성이 더 좋음
•
import
import re
Python
복사
1. 함수
1.1 match
•
문자열의 가장 앞(시작)에서부터 일치하는 패턴 찾기
•
re.match(패턴, 문자열)
s = "fast campus datascience fighitng. datascience fighting. fast campus fighting."
result1 = re.match("fast", s)
result2 = re.match("campus", s)
print("result1:", result1)
print("result2:", result2)
Python
복사
result1: <_sre.SRE_Match object; span=(0, 4), match='fast'>
result2: None
1.2 search
•
문자열에서 가장 첫번째로 일치하는 패턴 찾기 (일치하는 것 중 첫번째만)
•
re.search(패턴, 문자열)
result3 = re.search("fast", s)
result4 = re.search("campus", s)
print("result3:", result3)
print("result4:", result4)
Python
복사
result3: <_sre.SRE_Match object; span=(0, 4), match='fast'>
result4: <_sre.SRE_Match object; span=(5, 11), match='campus'>
1.3 findall
•
일치하는 패턴을 모두 찾아서 리스트로 돌려줌
•
가장 많이 사용하게됨
•
re.findall(패턴, 문자열)
result5 = re.findall("fast", s)
result6 = re.findall("campus", s)
print("result5:", result5, len(result5))
print("result6:", result6, len(result6))
Python
복사
result5: ['fast', 'fast'] 2
result6: ['campus', 'campus'] 2
1.4 split
•
패턴을 기준으로 문자열을 나눠서 리스트로 만들어 줌
•
re.split(패턴, 문자열)
•
여러가지 문자로 나누고 싶을 때
◦
string.split()은 chaining을 이용해 여러 번 함수를 호출해야함
◦
regex는 패턴을 이용해서 함수를 한번만 호출해도 됨
s1 = "fast campus datascience fighting!"
result = re.split("i", s1)
result
Python
복사
['fast campus datasc', 'ence f', 'ght', 'ng!']
1.5 sub
•
일치하는 패턴을 대체
•
re.sub(패턴, 바꿀 문자, (전체)문자열)
print(s)
re.sub("fast","slow", s)
Python
복사
fast campus datascience fighitng. datascience fighting. fast campus fighting.
'slow campus datascience fighitng. datascience fighting. slow campus fighting.'
2. Pattern
•
문자: 숫자인지 문자인지 특수문자인지 등을 구분
•
지정자: '범위가 몇회 반복' 같은 패턴을 구분
2.1 문자
•
\\d & \\D: 숫자와 비숫자를 찾는 패턴
•
\\w & \\W : 숫자, 문자, _ & 숫자, 문자, _ 제외
•
\\s & \\S: 공백문자 & 비공백문자
import string
# string.printable: 사용가능한 모든 문자
pt = string.printable
print(len(pt))
pt
Python
복사
100
'0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&\\'()*+,-./:;<=>?@[\\\\]^_`{|}~ \\t\\n\\r\\x0b\\x0c'
(1) \\d & \\D: 숫자와 비숫자를 찾는 패턴
result = re.findall("\\d", pt) # '\\d'라는 패턴을 findall 함수에 넣어줌
result
Python
복사
['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
result = re.findall("\\D", pt)
''.join(result)
Python
복사
'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&\\'()*+,-./:;<=>?@[\\\\]^_`{|}~ \\t\\n\\r\\x0b\\x0c'
(2) \\w & \\W : 숫자, 문자, _ & 숫자, 문자, _ 제외
•
숫자, 문자, _ : 식별자로 사용할 수 있는 문자
result = re.findall("\\w", pt)
''.join(result)
Python
복사
'0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_'
result = re.findall("\\W", pt)
''.join(result)
Python
복사
'!"#$%&\\'()*+,-./:;<=>?@[\\\\]^`{|}~ \\t\\n\\r\\x0b\\x0c'
(3) \\s & \\S: 공백문자 & 비공백문자
•
공백문자: 문자의 공백을 다 지우고 싶으면 이 패턴을 활용해서 sub 함수를 쓰면 됨
result = re.findall("\\s", pt)
''.join(result)
Python
복사
' \\t\\n\\r\\x0b\\x0c'
result = re.findall("\\S", pt)
''.join(result)
Python
복사
'0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&\\'()*+,-./:;<=>?@[\\\\]^_`{|}~'
2.2 지정자
지정자의 활용이 정규표현식의 핵심이라 할 수 있음!
•
[]: 문자
•
: 범위
•
.: 하나의 문자
•
?: 0회 또는 1회 반복
•
: 0회 이상 반복
•
+: 1회 이상 반복
•
{m,n}: m~n회 반복
•
(): 그룹핑
3. Examples
3.1 email 주소 찾기
s = "저의 이메일 주소는 hyeshinoh@gmail.com입니다. 또한 panda706@naver.com도 가지고 있습니다."
p = "[0-9a-zA-Z]+@[0-9a-z]+\\.[0-9a-z]+" # \\. : 패턴이 아니고 "."을 문자 자체로 사용
# result = True if re.search(p, s) else False
# print(result, re.findall(p, s))
re.findall(p, s)
Python
복사
['hyeshinoh@gmail.com', 'panda706@naver.com']
3.2 주민등록번호 뒷자리 변경
•
주민등록번호를 group으로 나눠서 뒷자리를 *******로 변경
s = "저의 전화번호는 010-1111-2222이고 주민등록번호는 870101-1234567 입니다"
p = "[0-9]{6}\\-[0-9]{7}" # \\(escaping)을 안해줘도 문제는 없음
print(re.findall(p, s))
p = "([0-9]{6})\\-([0-9]{7})" # 그룹핑
print(re.findall(p, s))
re.sub(p, "\\g<1>-********", s) # \\g<1> : 그룹핑 첫번째(0부터 세지 않음. 앞의 그룹) 데이터 사용
Python
복사
['870101-1234567']
[('870101', '1234567')]
'저의 전화번호는 010-1111-2222이고 주민등록번호는 870101-******** 입니다'
3.3 전화번호 추출해서 바꾸기
위 내용 전체를 jupyter notebook으로 보려면,
참고자료
•
패스트캠퍼스, ⟪데이터사이언스스쿨 8기⟫ 수업자료