2021. 1. 13. 10:23ㆍ교육과정/KOSMO
키워드 : 파이썬 예외 처리 / 파이썬 파일 읽고 쓰기 / 파이썬에서 csv, xml, json 사용하기 / 파이썬 정규식 표현 (유효성 검사 ) /
****
1. 파이썬 예외 처리
[에러와 예외] 1. 에러 문법적 오류 2. 예외 실행시 발생하는 오류로 예외가 발생하면 프로그램이 비정상 종료된다 |
[예외처리] try: 예외 발생 가능 문장들 except Exception: 예외가 발생한 후에 실행할 문장들 else: 예외가 발생하지 않았을 때 실행되는 문장들 finally: 예외 발생 여부와 상관없이 무조건 실행되는 문장들 [참고] 파이썬 내장 예외 https://docs.python.org/3/library/exceptions.html |
※ 파이썬에서 else는 반복문, 조건문, 예외처리 등에서 사용할 수 있어 유용하다.
(1) 예외처리 실습
① 10을 0으로 나눌 경우 예외가 발생하여 정상적으로 출력되지 않는다.
10/0
print('종료')
# 실행결과
'''
ZeroDivisionError: division by zero
'''
② try ~ except Excception 을 사용하여 예외가 발생했을 때 수행할 작업을 지정할 수 있다.
try:
10/0
except Exception:
print("예외")
# 실행결과
'''
예외
'''
③ except Excception 에 as 를 사용하여 예외가 발생했을 때 에러 내용을 출력할 수 있다.
try:
10/0
except Exception as e:
print("예외:", e)
else:
print("예외없음")
# 실행결과
'''
예외: division by zero
'''
④ try ~ except Excception ~ else 를 사용하여 예외가 발생하지 않고 정상 처리되었을 때
수행할 작업을 지정할 수 있다.
try:
10/1
except Exception as e:
print("예외:", e)
else:
print("예외없음")
# 실행결과
'''
예외없음
'''
2. 파이썬 파일 읽고 쓰기
@ 파일 읽고 쓰기 - 파일을 읽고 쓰기 전에 파일을 열어야 한다 - fileObj = open ( filename, mode ) |
@ mode 첫번째 글자 - 작업 표시 r(read) : 파일 읽기 w(write) : 파일 쓰기 ( 파일이 없으면 생성하고 파일이 있으면 덮어쓴다 ) x(write) : 파일 쓰기 ( 파일이 없을 때만 생성하고 쓴다 ) a(append) : 파일 추가 ( 파일이 있으면 파일의 끝에서부터 추가하여 쓴다 ) |
@ mode 두번째 글자 - 파일 타입 t : 텍스트(text) 타입 ( 기본값 ) b : 이진(binary) 타입 두번째 글자가 없으면 텍스트 타입이다. |
@ 한글처리는 이전에 사용을 했으면 하고, 사용하지 않았을 경우엔 적용하지 않아야 한다. 한글처리는 모든 파일에 무조건 하지 않고 필요한 경우에만 한다. encoding='utf-8' : 한글 |
@ 파일 닫기 - 파일을 열고 사용 후에는 반드시 닫아야 한다. - 간단한 파일의 경우 별다른 문제가 없으나, 다수의 파일로 작업할 경우, 원치 않는 데이터 처리가 발생할 수 있기 때문에 필요한 작업 직후 닫아준다. (통로는 기본적으로 바로 닫아주기 ! ) - 파일 객체를 자동으로 닫는 with 구문을 많이 사용한다. |
(1) mode의 첫번째 글자에서 ' r ' 을 기술하여 파일 읽기 작업을 할 경우
① 파일이 있을 경우
f = open('./data/data.txt', 'r', encoding='utf-8')
line = f.read()
print(line)
f.close()
# 실행결과
'''
안녕하세요 data.txt 파일입니다.
'''
② 파일이 없을 경우 ... 에러가 발생한다.
f = open('./data/data2.txt', 'r', encoding='utf-8')
line = f.read()
print(line)
f.close()
# 실행결과
'''
FileNotFoundError: [Errno 2] No such file or directory: './data/data2.txt'
'''
(2) 예외처리를 적용시킨 (1) 의 상황
※ 예외가 발생한 상황에서는 open 자체가 정상적으로 수행되지 않기 때문에 close 할 필요가 없다. |
① 파일이 있을 경우
try:
f = open('./data/data.txt', 'r', encoding='utf-8')
except Exception as e:
print('예외발생', e)
else:
line = f.read()
print(line)
f.close()
finally:
print('종료합니다.')
# 실행결과
'''
안녕하세요 data.txt 파일입니다.
종료합니다.
'''
② 파일이 없을 경우
try:
f = open('./data/data0.txt', 'r', encoding='utf-8')
except Exception as e:
print('예외발생', e)
else:
line = f.read()
print(line)
f.close()
finally:
print('종료합니다.')
# 실행결과
'''
예외발생 [Errno 2] No such file or directory: './data/data0.txt'
종료합니다.
'''
(3) 반복문을 사용하여 파일을 한 줄씩 읽다가 더 이상 내용이 없을 경우 반복문을 빠져나가게 하기
※ readline( )은 한 줄을 읽어온다.
try:
f = open('./data/data.txt', 'r', encoding='utf-8')
except Exception as e:
print('예외발생', e)
else:
while True:
line = f.readline()
if not line: break
print(line)
f.close()
finally:
print('종료합니다.')
(4) with 구문을 사용하면 파일을 열고 데이터를 읽는 작업이 끝난 뒤, 자동으로 파일 객체를 (close)닫아준다.
with open('./data/data.txt', 'r', encoding='utf-8') as f:
while True:
line = f.readline()
if not line: break
print(line)
print('종료합니다')
# 실행결과
'''
안녕하세요 data.txt 파일입니다.
종료합니다
'''
(5) 파일을 한 번에 읽은 뒤 단어 수를 출력할 수 있다.
with open('./data/data.txt', 'r', encoding='utf-8') as f:
content = f.read()
words = content.split()
print('단어수=',len(words))
print('종료합니다')
# 실행결과
'''
단어수= 3
종료합니다
'''
3. 파이썬 파일 읽고 쓰기 - 연습문제
※ 다음 조건을 충족하는 함수 count_words 를 완성 후 정상적으로 출력되는지 확인한다.
함수 정의 : count_words 인자 : filename 인자로 받은 파일명을 open 하여 파일을 읽어서 단어를 수를 출력한다. 존재하지 않는 파일명으로 예외가 발생해도 아무런 일을 하지 않는다 |
① 방법1
def count_words(filename):
try:
f = open('./data/'+filename, 'r', encoding='utf-8')
except Exception as e:
pass
else:
words = f.read().split()
print(filename, ' 단어수=',len(words))
f.close()
filenames = ['sample.xml', 'xxxx.xxx', 'temp.json']
for filename in filenames:
count_words(filename)
# 실행결과
'''
sample.xml 단어수= 31
temp.json 단어수= 19
''''
※ print(filename, ' 단어수=', len(words)) 대신 return print(filename, ' 단어수=', len(words)) 를 사용할 수도 있다.
② 방법 2
def count_words(filename):
try:
with open('./data/'+filename, 'r', encoding='UTF-8') as f:
print(filename, ' 단어수=', len(f.read().split()))
except Exception as e:
pass
# 존재하지 않는 파일명도 있음
filenames = ['sample.xml', 'xxxx.xxx', 'temp.json']
for filename in filenames:
count_words(filename)
# 실행결과
'''
sample.xml 단어수= 31
temp.json 단어수= 19
'''
③ 방법 3
def count_words(filename):
try:
f = open('./data/'+filename, 'r', encoding='UTF-8')
except Exception as e:
pass
else:
with f:
print(filename, ' 단어수=', len(f.read().split()))
# 존재하지 않는 파일명도 있음
filenames = ['sample.xml', 'xxxx.xxx', 'temp.json']
for filename in filenames:
count_words(filename)
# 실행결과
'''
sample.xml 단어수= 31
temp.json 단어수= 19
'''
4. 파이썬에서 csv 활용하기
※ 확장자명을 csv로 만들어두면 엑셀에서 읽을 수 있고, 다양한 작업이 가능하다.
단, 매우 큰 용량의 경우 엑셀로 처리가 불가능하기 때문에 이 경우에는 파이썬 등 다른 방법을 사용해야 한다.
※ csv : common string value 로 평범한 문자열의 데이터를 저장하는 형식
(1) 리스트의 데이터를 csv로 저장하기
① csv 로 파일을 읽고 쓰기 위해서는 패키지를 import 해야 한다.
import csv
② 저장할 데이터를 리스트 구조로 작성한다.
data = [ [1,'김길동','책임'], [2,'박길동','연구원'], [3,'최길동','선임'] ]
③ imsi.csv 라는 이름으로 파일을 저장하도록 with 구문을 작성한다.
writer( ) : 데이터를 저장하기 위한 가상 통로를 얻어온다. writerow( ) : 데이터를 한 줄식 보낸다. |
with open('./data/imsi.csv', 'wt', encoding='utf-8-sig') as f:
c_out = csv.writer(f)
c_out.writerow(data)
엑셀은 ANSI 코드로 디코딩해야 하므로 encoding='utf-8-sig' 라고 작성한다. |
(실행결과)
※ csv 파일을 엑셀에서 열 때 한글이 깨질 경우,
파일 우클릭 - 메모장으로 열기 - 다른이름으로 저장 - 인코딩을 'ANSI'로 변경 후 저장
→ 엑셀에서 정상적으로 글씨 출력된다.
(2) csv 파일의 리스트 데이터를 파이썬으로 읽어오기
data = []
with open('./data/imsi.csv', 'r', encoding='utf-8-sig') as f:
cin = csv.reader(f)
data = [row for row in cin if row]
print(data)
# 실행결과
'''
[["[1, '김길동', '책임']", "[2, '박길동', '연구원']", "[3, '최길동', '선임']"]]
'''
(+) 추가 ...... 컴프리핸션에서 조건문을 사용하지 않으려면,
# newline 설정을 하지 않으면 한 줄마다 공백 있는 줄이 들어가버린다.
# 즉, [3, 최길동, 선임] 뒤에 공백 셀 하나가 생긴다.
# 따라서 newline='' 을 설정해준다.
data = [[1, '김길동', '책임'], [2, '박길동', '연구원'], [3, '최길동', '선임']]
with open('./data/imsi.csv', 'wt', newline='', encoding='UTF-8-sig') as f:
cout = csv.writer(f)
cout.writerow(data)
with open('./data/imsi.csv', 'r', encoding='utf-8-sig') as f:
cin = csv.reader(f)
data = [row for row in cin]
print(data)
5. 파이썬 연습문제 - 파일처리와 예외처리
(1) 다음 코드의 실행 결과를 쓰시오.
try:
for i in range(1, 7):
result = 7 // i
print(result)
except ZeroDivisionError:
print("Not divided by 0")
finally:
print("종료되었습니다.")
답 :
7
3
2
1
1
1
종료되었습니다.
(2) 다음 코드를 실행했을 때, 가장 마지막에 출력되는 값은?
sentence = list("Hello Gachon")
while (len(sentence) + 1):
try:
print(sentence.pop(0))
except Exception as e:
print(e)
break
① o ② n ③ h ④ c ⑤ pop from empty list
답 : ⑤
(풀이)
sentence를 출력하면 ['H', 'e', 'l', 'l', 'o', ' ', 'G', 'a', 'c', 'h', 'o', 'n'] 이다.
len(sentence) 는 12가 되고 while문에 들어가는 수는 12+1 인 13 이된다.
pop(0) 함수에 의해 0번째 글자를 뽑는 작업을 13번 반복하는데
12번까지는 정상적으로 수행되지만, 13번째에는 list 에 남아있는 데이터가 없어서
pop from empty list 예외가 발생한다.
(3) 다음 각각의 예외 처리에 적합한 내장 예외(built-in exception)를 순서대로 실행한 결과값이 바르게 짝지어진 것은?
(가)
alist = ["a", "1", "c"]
blist = ["b", "2", "d"]
for a, b in enumerate(zip(alist, blist)):
print(b[a])
(나)
alist = ["a", "1", "c"]
blist = ["b", "2", "d"]
for a, b in enumerate(zip(alist, blist)):
print(a/int(b[0]))
① NameError, ValueError ② IndexError, NameError
③ ZeroDivisionError, ValueError ④ IndexError, ValueError ⑤ NameError, IndexError
답 : ④
(풀이)
Index Error : 인덱싱 범위를 넘어선 값이 주어졌을 때 발생하는 에러
Value Error : 데이터 타입이 맞지 않을 때 발생하는 에러
Name Error : 변수가 정의되어 있지 않을 때 발생하는 에러
ZeroDivisionError : 어떠한 수를 0으로 나눌 때 발생하는 에러
zip(alist, blist)의 결과는
('a', 'b')
('1', '2')
('c', 'd')
enumerate(zip(alist, blist)) 의 결과는
(0, ('a', 'b'))
(1, ('1', '2'))
(2, ('c', 'd'))
for a, b in enumerate(zip(alist, blist)) 의 경우
a b
(0, ('a', 'b'))
(1, ('1', '2'))
(2, ('c', 'd'))
b[a] 는 ('a', 'b')에서 0번째를 출력하면 'a'
('1', '2')에서 1번째를 출력하면 '2'
('c', 'd')에서 2번째를 출력하면 IndexError: tuple index out of range
a/int(b[0]) 는 ('a', 'b') 에서 b[0] 는 a 이므로 0/a 의 결과는 ValueError: invalid literal for int() with base 10: 'a'
('1', '2') 에서 b[0] 는 1 이므로 1/1 의 결과는 1
('c', 'd') 에서 b[0] 는 c 이므로 2/c 의 결과는 ValueError: invalid literal for int() with base 10: 'c'
(4) 다음 중 예외(exception)의 이름과 내용이 잘못 짝지어진 것은?
① ZeroDivisionError: 0으로 숫자를 나눌 때
② ValueError: 변환할 수 없는 문자/숫자를 변환할 때
③ IndexError: 리스트의 인덱스 범위를 넘어 갈 때
④ SyntaxError: 조건문이나 변수에 오탈자가 존재할 때
⑤ NameError: 존재하지 않은 변수를 호출할 때
답 : ④
(풀이)
Syntax Error 는 파이썬 문법에 맞지 않는 표현이 있을 경우 발생하는 구문 오류이다.
(5) 파일의 종류에 대한 설명으로 틀린 것은?
① 바이너리 파일은 컴퓨터만 이해할 수 있는 형태인 이진법 형식으로 저장된 파일을 말한다.
② 텍스트 파일의 예로 HTML, 파이썬 코드 파일 등을 들 수 있다.
③ 바이너리 파일은 해당 확장자에 대한 파일을 열 수 있는 프로그램이 필요하다(엑셀, 워드 등).
④ 텍스트 파일의 경우 컴퓨터는 텍스트 파일 형태 그대로 처리가 가능하다.
⑤ 텍스트 파일은 사람도 이해할 수 있는 형태인 문자열 형식으로 저장된 파일을 말한다.
답 : ④
(풀이)
컴퓨터는 텍스트 파일을 이진법 형식으로 변환한 뒤 처리한다.
(6) 다음 코드의 실행 결과를 쓰시오.
for i in range(3):
try:
print(i, 3// i)
except ZeroDivisionError:
print("Not divided by 0")
답 :
Not devided by 0
1 3
2 1
(7) 다음 코드는 파이썬에서 ‘i_have_a_dream.txt’ 파일을 읽어오는 코드이다.
같은 기능을 하는 코드를 with 구문과 함께 사용하여 작성하시오.
f = open("i_have_a_dream.txt", "r")
contents = f.read()
print(contents)
f.close()
답 :
with open("i_have_a_dream.txt", "r") as f:
contents = f.read()
print(contents)
(8) 바이너리 파일과 텍스트 파일에 대한 설명으로 틀린 것은?
① 텍스트 파일은 사람도 이해할 수 있는 형태로 저장된다.
② 메모장에 저장된 파일, HTML 파일, 파이썬 코드 파일 등은 모두 텍스트 파일이다.
③ 텍스트 파일은 컴퓨터만 이해할 수 있는 형태인 이진(법) 형식으로 저장된 파일이다.
④ 엑셀 파일, 워드 파일 등을 바이너리 파일이라고 부른다.
⑤ 모든 텍스트 파일도 실제는 바이너리 파일로 아스키/유니코드 문자열 집합으로 저장된다.
답 : ③
(풀이)
컴퓨터만 이해할 수 있는 파일은 바이너리 파일이다.
6. 파이썬에서 xml 활용하기
※ xml : 데이터를 안정적인 구조로 주고 받기 위해 사용한다.
(1) xml 파일을 사용하기 위해서 패키지를 import 한다.
import xml.etree.ElementTree as et
(2) ElementTree( ) 함수를 사용하여 xml 파일을 읽고 출력한다.
① ElementTree( ) 함수에 들어가는 인자는 키워드인자이므로 타입을 명시해줘야 한다. (위치인자가 아님)
② getroot( ) 함수는 xml 문서에서 최상위 루트 태그를 가져온다.
import xml.etree.ElementTree as et
tree = et.ElementTree(file = './data/temp.xml')
root = tree.getroot()
print('root : ', root)
# 실행결과
'''
root : <Element 'employees' at 0x00000256B0D73868> # ... 최상위 루트 태그는 employees
'''
(3) root.tag 로 루트 태그만 출력할 수 있다.
import xml.etree.ElementTree as et
tree = et.ElementTree(file = './data/temp.xml')
root = tree.getroot()
print('root tag : ', root.tag)
# 실행결과
'''
root tag : employees
'''
(4) 최상위 태그를 반복문의 집합요소로 하여 출력하면 하위에 있는 자식 태그를 출력할 수 있다.
import xml.etree.ElementTree as et
tree = et.ElementTree(file = './data/temp.xml')
root = tree.getroot()
for child in root:
print(child.tag)
# 실행결과
'''
employee
employee
employee
'''
(5) root의 자식에서 다시 한 번 자식을 출력하면 하위의 태그를 출력할 수 있다.
import xml.etree.ElementTree as et
tree = et.ElementTree(file = './data/temp.xml')
root = tree.getroot()
for child in root:
for jason in child:
print(jason.tag, end=' ')
# 실행결과
'''
no name job no name job no name job
'''
(6) .tag에서는 태그를, .test에서는 태그 안에 들어있는 텍스트를 출력할 수 있다.
import xml.etree.ElementTree as et
tree = et.ElementTree(file = './data/temp.xml')
root = tree.getroot()
for child in root:
for jason in child:
print(jason.tag, ':', jason.text)
# 실행결과
'''
no : 1
name : 김
job : 책임
no : 2
name : 박
job : 선임
no : 3
name : 이
job : 연구원
'''
7. 파이썬에서 json 활용하기
(1) json 파일을 사용하기 위해서는 패키지를 import 한다.
import json
(2) temp.json 파일을 읽은 결과, 단순 문자열로 출력된다.
f = open('./data/temp.json', 'r', encoding='utf-8')
data = f.read()
print(data)
print(type(data)) # <class 'str'>
# 실행결과
'''
{
"박열":{
"No":1,
"Job": "선임"
},
"김원봉":{
"No":2,
....
'''
(3) 읽어온 데이터가 json 구조를 가질 수 있도록 json.loads( ) 함수를 처리해준다.
출력결과는 딕셔너리 타입이 된다.
import json
f = open('./data/temp.json', 'r', encoding='utf-8')
data = f.read()
items = json.loads(data)
print(items)
print(type(items))
# 실행결과
'''
{'박열': {'No': 1, 'Job': '선임'}, '김원봉': {'No': 2, 'Job': '주임'}, '이순신': {'No': 3, 'Job': '연구원'}}
<class 'dict'>
'''
(4) 딕셔너리 구조를 갖는 items 에 print ( ) 함수를 적용하면 key에 해당하는 값만 출력된다.
import json
f = open('./data/temp.json', 'r', encoding='utf-8')
data = f.read()
items = json.loads(data)
for item in items:
print(item)
# 실행결과
'''
박열
김원봉
이순신
'''
(5) 딕셔너리 구조를 갖는 items로부터 key 뿐만 아니라 value를 출력할 수 있다.
① items[ ].get( ) 메소드를 사용
import json
f = open('./data/temp.json', 'r', encoding='utf-8')
data = f.read()
items = json.loads(data)
for item in items:
print(item, items[item].get('No'), items[item].get('Job'))
# 실행결과
'''
박열 1 선임
김원봉 2 주임
이순신 3 연구원
'''
② items( ) 함수를 사용하여 딕셔너리 구조를 튜플로 변환 후 추출
import json
f = open('./data/temp.json', 'r', encoding='utf-8')
data = f.read()
items = json.loads(data)
for item, values in items.items(): # items() 함수를 사용하여 튜플로 추출
for i, v in values.items():
print(i, v)
# 실행결과
'''
No 1
Job 선임
No 2
Job 주임
No 3
Job 연구원
'''
8. 파이썬에서 json 활용하기 - 연습문제
※ sample.json 파일을 읽어서 총 합계를 출력하기
import json
f = open('./data/sample.json', 'r', encoding='utf-8')
data = f.read()
fruits = json.loads(data)
print(fruits)
hap = 0
for fruit in fruits:
price = fruits[fruit].get('price')
cnt = fruits[fruit].get('count')
hap += price * cnt
print('{} {:2d}개 {:4d}원 (개당 {:3d}원)'.format(fruit, cnt, price * cnt, price))
print('총계 : {}원'.format(hap))
# 실행결과
'''
{'사과': {'price': 500, 'count': 3}, '망고': {'price': 200, 'count': 2}, '딸기': {'price': 400, 'count': 10}, '과자': {'price': 100, 'count': 10}, '커피': {'price': 10, 'count': 20}}
사과 3개 1500원 (개당 500원)
망고 2개 400원 (개당 200원)
딸기 10개 4000원 (개당 400원)
과자 10개 1000원 (개당 100원)
커피 20개 200원 (개당 10원)
총계 : 7100원
'''
9. 파이썬 정규식 표현
# [참고] 파이썬 정규식 표현 - https://docs.python.org/3/library/re.html - https://wikidocs.net/4308 > re |
# raw string - 문자열 앞에 r이 붙으면 해당 문자열이 구성된 그대로 문자열로 변환 |
a = 'abcdef\n' # escape 문자열 : \ 이후에 미리 예약된 문자가 온다.
b = r'abcdef\n'
print(a)
print(b)
# 실행결과
'''
abcdef
abcdef\n
'''
※ 패턴과 관련된 함수
# 패턴과 소스를 비교하는 함수 |
- (1) match() : 패턴의 일치여부 확인 search와 유사하나, 주어진 문자열의 시작부터 비교하여 패턴이 있는지 확인 시작부터 해당 패턴이 존재하지 않다면 None 반환 |
- (2) findall() : 일치하는 모든 문자열 리스트 반환 search가 최초로 매칭되는 패턴만 반환한다면, findall은 매칭되는 전체의 패턴을 반환 매칭되는 모든 결과를 리스트 형태로 반환 |
- (3) search() : 첫번째 일치하는 객체 반환 |
- (+) split() : 패턴에 맞게 소스를 분리한 후 문자열 조각의 리스트 반환 - (+) sub() : 주어진 문자열에서 일치하는 모든 패턴을 replace 그 결과를 문자열로 다시 반환함 count가 0인 경우는 전체를, 1이상이면 해당 숫자만큼 치환 됨 |
(1) match( ) : 패턴의 일치 여부 확인
① 별도의 정규식 표시가 없을 경우 원본 문자열의 시작부분부터 검사한다.
import re
msg = 'We are happy. You are happy. Happy2019 2020'
result = re.match('We', msg) # ... re.match('^We', msg) 와 같은 결과 ...^는 맨 앞을 뜻함
result2 = re.match('You', msg) # ... re.match('^You', msg) 와 같은 결과
print(result)
print(result2)
# 실행결과
'''
<re.Match object; span=(0, 2), match='We'>
None
'''
→ We 를 맨 앞에서 찾은 결과 match 되었다고 출력되고,
You를 맨 앞에서 찾은 결과 match 가 되지 않아 None 이라고 출력된다.
② match( ) 함수의 결과는 object 이기 때문에 찾은 단어를 출력하기 위해서는 group( ) 함수를 사용한다.
import re
msg = 'We are happy. You are happy. Happy2019 2020'
result = re.match('We', msg)
result2 = re.match('You', msg)
print(result.group())
# print(result2.group()) ........ 결과가 None 이기 때문에 에러 발생
if result2:
print(result.group2()) # ...... 결과가 있을 때만 출력하도록 함
# 실행결과
'''
We
'''
③ 정규식을 적용하여 happy와 같은 문자열이 있는지 확인할 수 있다.
import re
msg = 'We are happy. You are happy. Happy2019 2020'
result1 = re.match('.*happy', msg) # ... .은 문자가 일치함을, *은 0회 이상을 뜻함
result2 = re.match('.*2020', msg)
print(result.group())
if result:
print(result.group())
print(result2.group())
if result2:
print(result.group2())
# 실행결과
'''
<re.Match object; span=(0, 27), match='We are happy. You are happy'>
We are happy. You are happy
<re.Match object; span=(0, 43), match='We are happy. You are happy. Happy2019 2020'>
We are happy. You are happy. Happy2019 2020
'''
(2) findall( ) : 일치하는 모든 문자열 리스트 반환
import re
msg = 'We are happy. You are happy. Happy2019 2020'
result = re.findall('happy', msg)
if result:
print(result)
# 실행결과
'''
happy
'''
(3) search() : 첫번째 일치하는 객체 반환
: 패턴이 어디 있던지 찾아낸다.
import re
msg = 'We are happy. You are happy. Happy2019 2020'
result = re.search('happy', msg)
if result:
print(result)
# 실행결과
'''
['happy', 'happy']
'''
(+) split() : 패턴에 맞게 소스를 분리한 후 문자열 조각의 리스트 반환
import re
msg = 'We are happy. You are happy. Happy2019 2020'
result = re.split('a', msg)
if result:
print(result)
# 실행결과
'''
['We ', 're h', 'ppy. You ', 're h', 'ppy. H', 'ppy2019 2020']
'''
(+) sub() : 주어진 문자열에서 일치하는 모든 패턴을 replace
import re
msg = 'We are happy. You are happy. Happy2019 2020'
result = re.sub('a', '@', msg)
if result:
print(result)
# 실행결과
'''
We @re h@ppy. You @re h@ppy. H@ppy2019 2020
'''
10. 파이썬 정규식 표현 - 연습문제
※ 다른 모든 함수들도 정규식 표현으로 추출 및 검색 가능
# 기본 패턴 - a, X, 9 등등 문자 하나하나의 character들은 정확히 해당 문자와 일치 e.g) 패턴 test는 test 문자열과 일치 대소문자의 경우 기본적으로 구별하나, 구별하지 않도록 설정 가능 - 몇몇 문자들에 대해서는 예외가 존재하는데, 이들은 특별한 의미로 사용 됨 . ^ $ * + ? { } [ ] \ | ( ) - . (마침표) - 어떤 한개의 character와 일치 (newline(엔터) 제외) - \w - 문자 character와 일치 [a-zA-Z0-9_] - \s - 공백문자와 일치 - \t, \n, \r - tab, newline, return - \d - 숫자 character와 일치 [0-9] - ^ (시작), $(끝) : 각각 문자열의 시작과 끝을 의미 - \가 붙으면 스페셜한 의미가 없어짐. 예를들어 \\.는 .자체를 의미 \\\는 \를 의미 |
# [ ] 문자들의 범위를 나타내기 위해 사용 - [ ] 내부의 메타 캐릭터는 캐릭터 자체를 나타냄 - e.g) - [abck] : a or b or c or k - [abc.^] : a or b or c or . or ^ - [a-d] : -와 함께 사용되면 해당 문자 사이의 범위에 속하는 문자 중 하나 - [0-9] : 모든 숫자 - [a-z] : 모든 소문자 - [A-Z] : 모든 대문자 - [a-zA-Z0-9] : 모든 알파벳 문자 및 숫자 - [^0-9] : ^가 맨 앞에 사용 되는 경우 해당 문자 패턴이 아닌 것과 매칭 |
# \ (1) 다른 문자와 함께 사용되어 특수한 의미를 지님 - \d : 숫자 ......... [0-9] 와 동일 - \D : 숫자가 아닌 문자 ......... [^0-9] 와 동일 - \s : 공백 문자 (띄어쓰기, 탭, 엔터 등) - \S : 공백이 아닌 문자 - \w : 알파벳대소문자, 숫자 ......... [0-9a-zA-Z] 와 동일 - \W : non alpha-numeric 문자 ......... [^0-9a-zA-Z] 와 동일 (2) 메타 캐릭터가 캐릭터 자체를 표현하도록 할 경우 사용 - \\. , \\\ |
# 반복패턴 - 패턴 뒤에 위치하는 *, +, ?는 해당 패턴이 반복적으로 존재하는지 검사 - '+' -> 1번 이상의 패턴이 발생 - '*' -> 0번 이상의 패턴이 발생 - '?' -> 0 혹은 1번의 패턴이 발생 - 반복되는 패턴의 경우 greedy하게 검색 함, 즉 가능한 많은 부분이 매칭되도록 함 - e.g) a[bcd]*b 패턴을 abcbdccb에서 검색하는 경우 - ab, abcb, abcbdccb 전부 가능 하지만 최대한 많은 부분이 매칭된 abcbdccb가 검색된 패턴 |
① 소문자를 찾아서 반환
import re
msg = '2025 Happy year! We are so happy?'
result = re.findall('[a-z]', msg)
if result:
print(result)
# 실행결과
'''
['a', 'p', 'p', 'y', 'y', 'e', 'a', 'r', 'e', 'a', 'r', 'e', 's', 'o', 'h', 'a', 'p', 'p', 'y']
'''
(+) 소문자를 1개만 찾을 경우
import re
msg = '2025 Happy year! We are so happy?'
result = re.search('[a-z]', msg)
if result:
print(result.group())
# 실행결과
'''
a
'''
② 소문자가 아닌 것들을 찾아서 반환 (대괄호 안에 ^)
import re
msg = '2025 Happy year! We are so happy?'
result = re.findall('[^a-z]', msg)
if result:
print(result)
# 실행결과
'''
['2', '0', '2', '5', ' ', 'H', ' ', '!', ' ', 'W', ' ', ' ', ' ', '?']
'''
③ 대문자를 찿음
import re
msg = '2025 Happy year! We are so happy?'
result = re.findall('[A-Z]', msg)
if result:
print(result)
# 실행결과
'''
['H', 'W']
'''
④ +반복 옵셥으로 소문자를 연속해서 찾음 ( 즉, 단어 )
import re
msg = '2025 Happy year! We are so happy?'
result = re.findall('[a-z]+', msg)
if result:
print(result)
# 실행결과
'''
['appy', 'year', 'e', 'are', 'so', 'happy']
'''
⑤ 소문자와 대문자를 단어 단위로 찾음
import re
msg = '2025 Happy year! We are so happy?'
result = re.findall('[a-z]+', msg)
if result:
print(result)
result = re.findall('[A-Z]+', msg)
if result:
print(result)
# 실행결과
'''
['appy', 'year', 'e', 'are', 'so', 'happy']
['H', 'W']
'''
⑥ 숫자를 찾음
import re
msg = '2025 Happy year! We are so happy?'
result = re.findall('[0-9]', msg)
if result:
print(result)
# 실행결과
'''
['2', '0', '2', '5']
'''
⑦ +반복 옵션으로 숫자를 찾음
import re
msg = '2025 Happy year! We are so happy?'
result = re.findall('[0-9]+', msg) # ........ re.findall('\d+',msg) 과 동일
if result:
print(result)
# 실행결과
'''
['2025']
'''
⑧ 소문자, 대문자, 숫자가 아닌 문자들 ( 공백문자나 특수문자 )
import re
msg = '2025 Happy year! We are so happy?'
result = re.findall('\W', msg) # ........ re.findall('[^a-zA-Z0-9]', msg) 과 동일
if result:
print(result)
# 실행결과
'''
[' ', ' ', '!', ' ', ' ', ' ', ' ', '?']
'''
⑨ 문자 숫자 _ 를 검색
import re
msg = '2025 Happy year! We are so happy?'
result = re.findall('[\w_]', msg)
if result:
print(result)
# 실행결과
'''
['2', '0', '2', '5', 'H', 'a', 'p', 'p', 'y', 'y', 'e', 'a', 'r', 'W', 'e', 'a', 'r', 'e', 's', 'o', 'h', 'a', 'p', 'p', 'y']
'''
⑩ 영문자 숫자 _가 아닌 것들 검색
import re
msg = '2025 Happy year! We are so happy?'
result = re.findall('[^a-zA-Z0-9_]', msg)
if result:
print(result)
# 실행결과
'''
[' ', ' ', '!', ' ', ' ', ' ', ' ', '?']
'''
⑪ 숫자가 아닌 것들 검색
import re
msg = '2025 Happy year! We are so happy?'
result = re.findall('\D', msg)
if result:
print(result)
# 실행결과
'''
[' ', 'H', 'a', 'p', 'p', 'y', ' ', 'y', 'e', 'a', 'r', '!', ' ', 'W', 'e', ' ', 'a', 'r', 'e', ' ', 's', 'o', ' ', 'h', 'a', 'p', 'p', 'y', '?']
'''
11. 파이썬 컴파일 (compile)
# compile - 동일한 정규표현식을 매번 다시 쓰기 번거로움을 해결 - compile로 해당표현식을 re.RegexObject 객체에 저장하여 사용가능 |
※ 패턴을 만들고 해당되는 데이터를 찾아 출력할 수 있다.
[\w-] : 문자와 - 기호 |
import re
pattern = re.compile(r'[\w-]+@[\w.]+')
result = pattern.search('test@gmail.com hahahaha goood')
result2 = pattern.findall('test@gmail.com hahahaha goood')
if result:
print(result.group())
print(result2)
# 실행결과
'''
test@gmail.com
['test@gmail.com']
'''
※ 리스트에서 패턴에 해당되는 데이터를 찾아 출력하되, 람다 함수를 사용하여 출력할 수 있다.
https? : http 또는 https [\w.] : 문자와 숫자 그리고 . 기호 \w+$ : 문자로 끝남 |
import re
webs = ['http://www.test.co.kr', # 출력
'https://www.test1.com', # 출력
'http://www.test.com', # 출력
'ftp://www.test.com', # X
'http:://www.test.com', # X
'htp://www.test.com', # X
'http://www.google.com', # 출력
'https://www.homepage.com.'] # X
pattern = re.compile(r'https?://[\w.]+\w+$')
result = list(map(lambda w:pattern.search(w), webs))
# print(result)
for url in result:
# print(url.group()) # AttributeError: 'NoneType' 에러 발생
if url:
print(url.group())
# 실행결과
'''
[<re.Match object; span=(0, 21), match='http://www.test.co.kr'>, <re.Match object; span=(0, 21), match='https://www.test1.com'>, <re.Match object; span=(0, 19), match='http://www.test.com'>, None, None, None, <re.Match object; span=(0, 21), match='http://www.google.com'>, None]
http://www.test.co.kr
https://www.test1.com
http://www.test.com
http://www.google.com
'''
12. 파이썬 컴파일 - 연습문제 ( 파이썬에서의 유효성 검사 )
이메일 주소의 적합성 체크 kim@encore.com : 올바른 이메일 kim@encore : 잘못된 이메일 ( . 이 없음) k!m@encore.com : 잘못된 이메일 (특수문자 ! 안 됨) !km@encore.com : 잘못된 이메일 (특수문자 ! 안 됨) [참고] ^[ ] : 시작 [^] : not {2,9} : 최소 2개 최대 9개 {2,} : 최소 2개만 지정하고 최대는 지정하지 않음 $ : 끝 |
import re
def email_check(email):
pattern = re.compile('^[\w-]+@[\w]+\\.[\w]+$') # (r'^[\w-]+@[\w]+\.[\w]+$') 과 동일
result = pattern.search(email)
if result:
print('올바른 이메일')
else:
print('잘못된 이메일')
email_check('kim@encore.com')
email_check('kim@encore')
email_check('k!m@encore.com')
email_check('!km@encore.com')
# 실행결과
'''
올바른 이메일
잘못된 이메일
잘못된 이메일
잘못된 이메일
'''
# 참고용
pattern = re.compile(r'[^-=+,#/\?:^$.@*\"※~&%ㆍ!』\\‘|\(\)\[\]\<\>`\'…》][a-zA-Z0-9]+@[\w.]+com$')
비밀번호 생성시 의 적합성 체크 1. 비밀번호의 길이는 6-10 2. 숫자와 알파벳으로만 구성되어야 함 3. 대문자와 소문자가 섞여야 함 ( 대문자 1개 이상, 소문자 0개 이상) 4. 위의 조건에 부합하면 잘못된 상황을 출력하고 조건을 모두 만족하면 가능한 비밀번호임을 출력한다. |
import re
def pwd_check(pwd):
pattern = re.compile(r'[a-z]')
result = pattern.search(pwd)
if result:
return result
pwd_check('abcdE') # 길이오류
pwd_check('abcdef') # 대문자 포함하지 않아 오류
pwd_check('Abcdef2') # 성공
pwd_check('Abcdef_2') # 특수문자 포함