Search

Python 11. 정규표현식(regex)

Created at
2019/02/21
Updated at
2021/01/21
Tags
Keywords
3 more properties
목차

정규표현식

특정 패턴을 이용해 문자열을 처리하는 방법
호불호가 있지만 강사님은 필요시에만 사용하는 것이 좋다고 생각함
작성하면서 실수하기도 쉽고, 이해하는데도 가독성이 떨어짐
문자열 함수를 쓰는 것이 가독성이 더 좋음
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기⟫ 수업자료