이해하기 쉽고, 장황하지 않은 자료를 기반으로 강의를 진행합니다.
잔재미코딩 소식 공유
좀더 제약없이, IT 컨텐츠를 공유하고자, 자체 온라인 강의 사이트와 유투브 채널을
오픈하였습니다
응원해주시면, 곧 좋은 컨텐츠를 만들어서 공유하겠습니다
응원해주시면, 곧 좋은 컨텐츠를 만들어서 공유하겠습니다
● 잔재미코딩 유투브 오픈
[구독해보기]
4. 정규표현식¶
프로그래밍 연습(생각만 해보기)
다음 코드를 실행해보고, 이름 정보를 통해 남자인지, 여자인지, 기타인지(남녀 구별 불가)를 확인할 수 있는 방법 생각해보기
다음 코드를 실행해보고, 이름 정보를 통해 남자인지, 여자인지, 기타인지(남녀 구별 불가)를 확인할 수 있는 방법 생각해보기
import openpyxl엑셀파일 열기¶
work_book = openpyxl.load_workbook('data/train.xlsx')
현재 Active Sheet 얻기¶
work_sheet = work_book.active
work_sheet.rows는 해당 쉬트의 모든 행을 객체로 가지고 있음¶
for each_row in work_sheet.rows: print (each_row[3].value)
work_book.close()
세 라인의 코드를 추가하면 이름의 특징을 추출할 수 있음¶
import re regex = re.compile('[A-Za-z]+\.') print (regex.findall(each_row[3].value))
In [ ]:
import openpyxl
import re
regex = re.compile(' [A-Za-z]+\.')
# 엑셀파일 열기
work_book = openpyxl.load_workbook('data/train.xlsx')
# 현재 Active Sheet 얻기
work_sheet = work_book.active
# work_sheet.rows는 해당 쉬트의 모든 행을 객체로 가지고 있음
for each_row in work_sheet.rows:
print (each_row[3].value)
print (regex.search(each_row[3].value))
print (regex.findall(each_row[3].value))
work_book.close()
'[A-Za-z]+.' --> regular expression 이라고 함¶
- 특정한 규칙을 가진 문자열의 집합을 표현하는 데 사용하는 형식
정규 표현식 | 축약 표현 | 사용 예 |
---|---|---|
[0-9] | \d | 숫자를 찾음 |
[^0-9] | \D | 숫자가 아닌 것을 찾음(텍스트, 특수 문자, white space(스페이스, 탭, 엔터 등등)를 찾을 때) |
[ \t\n\r\f\v] | \s | white space(스페이스, 탭, 엔터 등등) 문자인 것을 찾음 |
[^ \t\n\r\f\v] | \S | white space(스페이스, 탭, 엔터 등등) 문자가 아닌 것을 찾음(텍스트, 특수 문자, 숫자를 찾을 때) |
[A-Za-z0-9] | \w | 문자, 숫자를 찾음 |
[^A-Za-z0-9] | \W | 문자, 숫자가 아닌 것을 찾음 |
예: 문자, 숫자가 아닌 데이터를 찾아서, '' 로 대체해라(삭제해라)¶
In [ ]:
import re
string = "(Dave)"
re.sub('[^A-Za-z0-9]', '', string) # 문자, 숫자가 아닌 데이터를 찾아서, '' 로 대체해라(삭제해라)
위 정규 표현식은 일정한 규칙을 가지고 작성됨, 필요한 패턴은 직접 만들 수도 있음¶
4.1. Dot .¶
- Dot . 메타 문자는 줄바꿈 문자인 \n를 제외한 모든 문자(한 개)를 의미함
- 예: D.A 는 D + 모든 문자(한 개) + A 를 의미
- DAA, DvA, D1A
정규 표현식 라이브러리 임포트하기¶
In [ ]:
import re
정규 표현식 패턴 만들기¶
In [ ]:
pattern = re.compile('D.A')
패턴에 매칭되는지 여부 확인하기 (실습)¶
In [ ]:
pattern.search("DAA")
In [ ]:
pattern.search("D1A")
In [ ]:
pattern.search("D00A")
In [ ]:
pattern.search("DA")
In [ ]:
pattern.search("d0A")
In [ ]:
pattern.search("d0A D1A 0111")
정말 Dot . 이 들어간 패턴을 찾으려면?¶
\. 으로 표시하거나, [.] 으로 표시하면 됨
In [ ]:
pattern = re.compile('D\.A')
In [ ]:
pattern.search("D.A")
In [ ]:
pattern.search("DDA")
In [ ]:
pattern = re.compile('D[.]A')
In [ ]:
pattern.search("D.A")
찾고 바꾸기 (특정 패턴이 매칭되는 것을 찾아서, 다른 문자열로 바꾸기)¶
In [ ]:
string = "(Dave)"
In [ ]:
# re.sub(패턴, 바꿀데이터, 원본데이터)
re.sub('[^A-Za-z0-9]', '', string) # 문자, 숫자가 아닌 데이터를 찾아서, '' 로 대체해라(삭제해라)
In [ ]:
# re.sub(패턴, 바꿀데이터, 원본데이터)
re.sub('[^A-Za-z0-9]', '--------------', string) # 문자, 숫자가 아닌 데이터를 찾아서, '' 로 대체해라(삭제해라)
In [ ]:
string = "-----(Dave)!@ "
In [ ]:
re.sub('[^A-Za-z0-9]', '', string) # 문자, 숫자가 아닌 데이터를 찾아서, '' 로 대체해라(삭제해라)
In [ ]:
string = "1-----(Dave)!@ 1"
re.sub('[^A-Za-z0-9]', '', string) # 문자, 숫자가 아닌 데이터를 찾아서, '' 로 대체해라(삭제해라)
4.2. 반복 ? , * , +¶
- ? 는 앞 문자가 0번 또는 1번 표시되는 패턴 (없어도 되고, 한번 있어도 되는 패턴)
- * 는 앞 문자가 0번 또는 그 이상 반복되는 패턴
- + 는 앞 문자가 1번 또는 그 이상 반복되는 패턴
? 사용 예¶
In [ ]:
pattern = re.compile('D?A') # 앞에 문자 D가 없거나, 여러번 반복되고 마지막이 A 인 문자열
In [ ]:
pattern.search("A")
In [ ]:
pattern.search("DA")
In [ ]:
pattern.search("DDA")
In [ ]:
* 사용 예¶
In [ ]:
pattern = re.compile('D*A') # 앞에 문자 D가 없거나, 여러번 반복되고 마지막이 A 인 문자열
In [ ]:
pattern.search("A")
In [ ]:
pattern.search("DA")
In [ ]:
pattern.search("DDDDDDDDDDDDDDDDDDDDDDDDDDDDA")
In [ ]:
pattern = re.compile('AD*A') # 앞에 문자 D가 없거나, 여러번 반복되고 마지막이 A 인 문자열
In [ ]:
pattern.search("ADA")
In [ ]:
pattern.search("ADDDDDDDDDDDDDDDDDDA")
In [ ]:
+ 사용 예¶
In [ ]:
pattern = re.compile('D+A')
In [ ]:
pattern.search("A")
In [ ]:
pattern.search("DA")
In [ ]:
pattern.search("DDDDDDDDDDDDDDDDDDDDDDDDDDDDA")
또다른 반복 표현: {n}, {m,n}¶
- {n} : 앞 문자가 n 번 반복되는 패턴
- {m, n} : 앞 문자가 m 번 반복되는 패턴부터 n 번 반복되는 패턴까지
{n} 사용 예¶
In [ ]:
pattern = re.compile('AD{2}A')
In [ ]:
pattern.search("ADA")
In [ ]:
pattern.search("ADDA")
In [ ]:
pattern.search("ADDDA")
{m,n} 사용 예¶
In [ ]:
pattern = re.compile('AD{2,6}A') # {m,n} 은 붙여 써야 함 {m, n} 으로 쓰면 안됨(특이함)
In [ ]:
pattern.search("ADDA")
In [ ]:
pattern.search("ADDDA")
In [ ]:
pattern.search("ADDDDDDA")
4.3. [ ] 괄호 : 괄호 안에 들어가는 문자가 들어 있는 패턴¶
- 예: [abc] 는 a, b, c 중 하나가 들어 있는 패턴을 말함
In [ ]:
pattern = re.compile('[abcdefgABCDEFG]')
In [ ]:
pattern.search("a1234")
In [ ]:
pattern.search("z1234")
하이픈(-)을 이용하면 알파벳 전체를 나타낼 수 있음¶
- 예: [a-c] 는 a, b, c 중 하나가 들어 있는 패턴을 말함
In [ ]:
pattern = re.compile('[a-z]')
In [ ]:
pattern.search("k1234")
In [ ]:
pattern.search("Z1234")
[a-zA-Z] 으로 표기하면 대소문자를 모두 포함해서 알파벳 전체를 나타낼 수 있음¶
In [ ]:
pattern = re.compile('[a-zA-Z]')
In [ ]:
pattern.search("Z1234")
[a-zA-Z0-9] 로 표기하면 대소문자를 모두 포함해서 알파벳 전체와 함께 숫자 전체도 나타낼 수 있음¶
In [ ]:
pattern = re.compile('[a-zA-Z0-9]')
In [ ]:
pattern.search("1234---")
In [ ]:
pattern.search("---------------!@#!@$!$%#%%%#%%@$!$!---")
[ ] 괄호 안에서 [ 바로 뒤에 ^ 을 쓰면 그 뒤에 오는 문자가 아닌 패턴을 찾음¶
- 문자를 결국 알파벳, 숫자, 특수문자, whitespace(스페이스, 탭, 엔터등) 로 분류할 수 있으므로
- [^ \t\n\r\f\v] 는 이중에서 whitespace 가 아닌 알파벳, 숫자, 특수문자를 지칭함
In [ ]:
pattern = re.compile('[^a-zA-Z0-9]')
In [ ]:
pattern.search("---------------!@#!@$!$%#%%%#%%@$!$!---")
In [ ]:
In [ ]:
pattern = re.compile('[^ \t\n\r\f\v]')
In [ ]:
pattern.search("-")
In [ ]:
pattern.search(" ")
그러면 한글만? --> [가-힣]¶
In [ ]:
pattern = re.compile('[가-힣]')
In [ ]:
pattern.search("안")
4.4. 조합해서 써보자¶
In [ ]:
import re
pattern = re.compile('[a-zA-Z]+')
matched = pattern.search("Dave")
print(matched)
4.5. 정규 표현식 라이브러리 함수 사용법¶
match 와 search 함수¶
- match : 문자열 처음부터 정규식과 매칭되는 패턴을 찾아서 리턴
- search : 문자열 전체를 검색해서 정규식과 매칭되는 패턴을 찾아서 리턴
In [ ]:
import re
pattern = re.compile('[a-z]+')
In [ ]:
matched = pattern.match('Dave')
In [ ]:
searched = pattern.search("Dave")
In [ ]:
print (matched)
In [ ]:
print (searched)
findall 함수: 정규표현식과 매칭되는 모든 문자열을 리스트 객체로 리턴함¶
In [ ]:
import re
pattern = re.compile('[a-z]+')
findalled = pattern.findall('Game of Life in Python')
In [ ]:
print (findalled)
In [ ]:
pattern2 = re.compile('[A-Za-z]+')
In [ ]:
findalled2 = pattern2.findall('Game of Life in Python')
In [ ]:
print (findalled2)
finditer 함수: 정규표현식과 매칭되는 모든 문자열을 iterator 객체로 리턴함¶
In [ ]:
import re
pattern2 = re.compile('[A-Za-z]+')
finded_data = pattern2.finditer('Game of Life in Python')
In [ ]:
for finded in finded_data:
print (finded) # 각각은 match 객체임
match 객체 주요 함수¶
- group() : 매칭된 문자열 리턴
- start() : 매칭된 문자열의 시작 위치 리턴
- end() : 매칭된 문자열 끝 위치 리턴
- span() : 매칭된 문자열의 (시작, 끝) 위치를 튜플로 리턴
In [ ]:
import re
pattern2 = re.compile('[A-Za-z]+')
finded_data = pattern2.finditer('Game of Life in Python')
In [ ]:
for finded in finded_data:
print (finded.group())
print (finded.start())
print (finded.end())
print (finded.span())
split 함수: 찾은 정규표현식 패턴 문자열을 기준으로 문자열을 분리¶
In [ ]:
import re
pattern2 = re.compile(':')
splited = pattern2.split('python:java')
In [ ]:
print (splited)
프로그래밍 연습
' VS ' 로 문자열 앞뒤를 분리해보기
' VS ' 로 문자열 앞뒤를 분리해보기
In [ ]:
import re
pattern2 = re.compile(' [A-Z]{2} ')
splited = pattern2.split('python VS java')
print (splited)
sub 함수: 찾은 정규표현식 패턴 문자열을 다른 문자열로 변경¶
In [ ]:
import re
pattern2 = re.compile('-')
subed = pattern2.sub('*', '801210-1011323') # sub(바꿀문자열, 본래문자열)
In [ ]:
print (subed)
In [ ]:
subed = re.sub('-', '*', '801210-1011323') # sub(정규표현식, 바꿀문자열, 본래문자열)
In [ ]:
print (subed)
In [ ]:
In [ ]:
801210-*******
도전 과제
주민번호 뒷자리를 * 로 바꿔서 가려보기
re.sub('-------', '------', each_row[1].value) <--- 정규표현식, 바꿀문자열 을 넣어봅니다.
주민번호 뒷자리를 * 로 바꿔서 가려보기
re.sub('-------', '------', each_row[1].value) <--- 정규표현식, 바꿀문자열 을 넣어봅니다.
import openpyxl work_book = openpyxl.load_workbook('data/data_kr.xlsx') work_sheet = work_book.active for each_row in work_sheet.rows: print(re.sub('-------', '------', each_row[1].value))work_book.close()
In [ ]:
import openpyxl
work_book = openpyxl.load_workbook('data/data_kr.xlsx')
work_sheet = work_book.active
for each_row in work_sheet.rows:
print(re.sub('-[0-9]{7}', '-*******', each_row[1].value))
work_book.close()