Study Web Development

3월 24일

이전으로

Python

정규표현식

  1. 새 파일 s02_regexp2.py 생성
import re

# findall(): 패턴을 문자열에서 모두 찾아서 리스트로 반환
number = 'My number is 1234-1*** and yours is 5678-2***'
p = re.findall(r'\d{4}', number)
print(p)
print('-'*3)

example = '17 정유년에 탄핵이 있었습니다. 20년에 총선이 있었습니다. 지금은 2022년입니다.'
# 숫자로 시작하고(\d), 어떤 문자든(.) 최소 1번 이상 반복되며(+), '년'으로 끝나는 문자열 반환
p = re.findall(r'\d.+년',example)
print("r'\d.+년':",p)
print('-'*3)

p = re.findall(r'\d.+?년',example) # 0~1번 사용되면 매치
print("r'\d.+?년':",p)
print('-'*3)

p = re.findall(r'\d+.년',example)
print("r'\d+.년':",p)
print('-'*3)

p = re.findall(r'\d+년',example)
print("r'\d+년':",p)
print('-'*3)

example = 'A는 다음과 같이 설명하였다(A, 2019). 이에 대해 B는 제시된 증거를 인과 관계로 해석하기 어렵다는 점을 지적하였다(B, 2019). 한편 다른 관점에서의 비판도 제기되었다(가나다, 2018).'
result = re.findall(r'\([A-Za-z가-힣]+, \d+\)',example)
print(result)
  1. 새 파일 s03_regexp3.py 생성
import re

# match(): 문자열의 처음부터 정규식과 매치되는지를 조사하고, 매치되지 않으면 None 반환
script = 'life'

p = re.match(r'life',script)
print(p)
print('-'*3)

# group(): 매치된 내용을 반환; 매치되지 않으면 오류 발생
p2 = re.match(r'life',script).group()
print(p2)
print('-'*3)

# span(): 매치된 문자열의 시작과 끝 직후 인덱스를 튜플로 반환
p2 = re.match(r'life',script).span()
print(p2)
  1. 새 파일 s04_regexp4.py 생성
import re

def refinder(pattern,script):
    if re.match(pattern, script):
        print('Matched')
    else:
        print('Not Found')

refinder(r'Life','Life is so cool') # Matched
refinder(r'life','Life is so cool') # Not Found; 대소문자 불일치
refinder(r'is','Life is so cool') # Not Found; 중간에 있는 패턴은 찾지 못함
print('-'*3)

#search(): 문자열 전체를 검색하여 정규식과 매치되는지 조사하고, 매치되지 않으면 None 반환
p = re.search(r'is', 'Life is so cool')
print(p)
p2 = re.search(r'is', 'Life is so cool').group()
print(p2)
p3 = re.search(r'is', 'Life is so cool').span()
print(p3)

5. 함수

파일 읽고 쓰기

.csv
  1. 새 파일 a.csv 생성하여 읽어올 데이터를 임의로 넣고 새 파일 s05_csv.py 생성
import csv

# 읽기 모드로 a.csv 파일 열기
f = open('a.csv','r',encoding='UTF-8')

new = csv.reader(f)
print(new)
print('-'*3)

# csv 파일 정보(객체)로부터 데이터 추출
for i in new:
    print(i) # 리스트 반환
print('-'*3)

# 파일의 내용을 읽으면 커서가 마지막으로 이동해 있기 때문에 다시 파일을 읽으려면 커서를 처음으로 되돌려야 함
f.seek(0)

a_list = []
for i in new:
    a_list.append(i)
print(a_list)

f.close()
  1. 새 파일 usecsv.py 생성
import csv,re

# .csv를 리스트로 바꾸기 위해 함수 정의
def opencsv(filename,enc):
    f = open(filename,'r',encoding=enc)
    reader = csv.reader(f)
    output = []
    for i in reader:
        output.append(i)
    f.close()
    return output

# csv형 리스트가 저장된 객체를 파일에 쓸 때
def writecsv(filename,enc,the_list):
    with open(filename,'w',encoding=enc,newline='') as f:
        writer = csv.writer(f,delimiter=',')
        writer.writerows(the_list)
    f.close()
  1. 새 파일 example2.csv 생성하여 읽어올 데이터를 임의로 넣고 새 파일 s06_csv2.py 생성
from usecsv import opencsv # 모듈 자체가 아니라 모듈의 함수를 import하면 모듈명을 생략하고 함수명만으로 호출 가능

print(opencsv('example2.csv','UTF-8'))
  1. 새 파일 s07_csv3.py 생성
import csv

a = [['구','전체','내국인','외국인'],
     ['관악구','519864','502089','17775'],
     ['강남구','547602','542498','5104'],
     ['송파구','686181','679247','6934'],
     ['강동구','428547','424235','4312']]

# newline을 빈 문자열로 전달하지 않으면 줄바꿈이 2회 발생
f = open('abc.csv','w',encoding='UTF-8',newline='')
# csv 파일의 구분자 지정
csvobject = csv.writer(f,delimiter=',')

# writerows(): csv형 리스트가 저장된 객체를 파일에 쓸 때 사용
csvobject.writerows(a)
print('csv 파일을 생성하였습니다')
f.close()
  1. 새 파일 s08_csv4.py 생성
from usecsv import writecsv

a = [['구','전체','내국인','외국인'],
     ['관악구','519864','502089','17775'],
     ['강남구','547602','542498','5104'],
     ['송파구','686181','679247','6934'],
     ['강동구','428547','424235','4312']]

writecsv('abc2.csv', 'UTF-8', a)
print('csv 파일이 생성되었습니다')

공공 데이터

.csv

서울 인구
  1. 새 파일 s09_csv5.py 생성
import usecsv,re

# 2차원 리스트 형태의 csv 정보
total = usecsv.opencsv('popSeoul.csv', 'UTF-8')

for i in total[:5]: # 인덱스 0부터 4까지만
    print(i)
print('-'*3)

i = total[2]
print(i)
print('-'*3)

k = []
for j in i:
    if re.search(r'\d',j): # 문자열의 처음뿐만 아니라 중간부터라도 패턴과 일치하는 부분이 있는지 검색
        k.append(float(re.sub(',','',j))) # re.sub(정규표현식,치환 문자,문자열)
    else:
        k.append(j)
print('숫자 검색',k)
print('-'*3)

k = []
for j in i:
    if re.search('[a-z가-힣!]',j): # 알파벳 소문자, 한글, 특수문자 ! 검색
        k.append(j)
    else:
        k.append(float(re.sub(',','',j)))
print('문자 검색',k)
print('-'*3)

# 예외 처리로 오류를 넘겨서 조건을 단순화함
i = ['123!!','151,767','11,093','27394','','!!!$%']
for j in i: # j는 값 자체이므로 인덱스를 따로 계산해야 함
    try:
        i[i.index(j)] = float(re.sub(',','',j))
    except:
        pass # 일부 코드가 구문상 필요하지만 어떤 작업도 하고 싶지 않은 경우
print(i) # 숫자로 변환 실패한 값들은 그대로 유지됨
print('-'*3)

다음으로