[인공지능사관학교] Python (7)

Suhyeon Lee·2025년 6월 25일

"기록이 없으면 역사도 없고 자신의 세계도 없다. 이것이 군중 속에서 군중으로 흔적 없이 매몰되는 자신을 잊지 않는 일이다." <구본형>

텍스트 파일 입출력

텍스트 자료 읽기

  • 읽기 모드(mode='r')로 객체를 생성할 경우 아래와 같은 텍스트 자료 읽기 관련 함수를 제공
    • read()
      • 전체 텍스트 자료를 한 번에 읽음
      • 읽어온 자료는 문자열(str) 자료형으로 반환됨
    • readlines()
      • 전체 텍스트 자료를 줄 단위로 읽음
      • 읽어온 자료는 리스트(list) 자료형으로 반환됨
    • readline()
      • 한 줄 단위로 읽음
      • 읽어온 자료는 문자열(str) 자료형으로 반환

예시

# 파일 읽기 관련 함수
try:
    # (1) read(): 전체 텍스트 자료 읽기
    ftest = open('data/ftest.txt', mode='r')
    full_text = ftest.read()
    print(full_text)
    print(type(full_text))

    # (2) readlines(): 전체 텍스트 줄 단위 읽기
    ftest = open('data/ftest.txt', mode='r')
    lines = ftest.readlines() # list 반환
    print(lines)
    print(type(lines)) # <class 'list>
    print('문단 수:', len(lines))
    
    # (3) list -> 문장 추출
    docs = [] # 문장 저장
    for line in lines:
        print(line.strip()) # text만 출력
        docs.append(line.strip())
    print(docs)
    
    # (4) readline(): 한 줄 읽기
    ftest = open('data/ftest.txt', mode='r')
    line = ftest.readline()
    print(line)
    print(type(line)) # <class 'str>

except Exception as e:
    print('Error 발생:', e)

finally:
    # 파일 객체 닫기
    ftest.close()

(1) read(): 전체 텍스트 자료 읽기

  • read() 함수는 ftest.txt 파일의 전체 내용을 문자열로 읽어온다.

(2) readlines(): 전체 텍스트 줄 단위 읽기

  • readlines() 함수는 전체 텍스트를 줄 단위로 읽어서 리스트 자료형으로 반환
    • 리스트 원소 한 개 == 텍스트 파일의 한 줄

(3) list -> 문장 추출

  • 텍스트 파일: 한 줄의 끝 부분에 줄바꿈(\n) 이스케이프 문자가 포함
    • 이러한 이스케이프 문자를 불용어로 보고 이를 제거하기 위해 문자열 객체에서 지원하는 strip() 함수 사용
  • strip() 함수를 이용하여 x변수의 문자열 끝 부분에 오는 \n, 공백, \t, \r 등의 이스케이프 문자 제거
x = "sgat3sgaga\n \t\r"
print(x.strip())

# 실행 결과
# sgat3sgaga

(4) readline(): 한 줄 읽기

  • readline() 함수는 텍스트 파일에서 순서대로 한 줄 단위로 읽어서 문자열(str) 반환
  • 6줄 전체를 읽기 위해서는 for문을 이용해 6번 반복하여 readline() 함수 호출
for i in range(6):
    line = ftest.readline()
    print(line.strip())

with 블록과 인코딩 방식

with open(file, mode, encoding) as 참조변수:
    pass
  • with 명령어를 이용해 블록 형식으로 파일 객체를 생성하는 방법
    • 블록 내에서 참조변수를 이용하여 파일 객체를 사용할 수 있고, 블록을 벗어나면 자동으로 객체가 close된다.
    • with 블록을 벗어나면 자동으로 객체가 소멸되기 때문에 finally 블록의 내용을 생략
try:
    with open('data/ftest3.txt', mode='w', encoding='utf-8') as ftest:
        ftest.write('파이썬 파일 작성 연습')
        ftest.write('파이썬 파일 작성 연습2')
        # with 블록 벗어나면 자동 close

    with open('data/ftest3.txt', mode='r', encoding='utf-8') as ftest:
        print(ftest.read())

except Exception as e:
    print('Error 발생:', e)

finally:
    pass
  • 첫 번째 with 블록은 data 폴더에 ftest3.txt 파일을 쓰기 모드로 파일 객체를 생성하고 참조변수인 ftest에 주소를 할당함
    • 파일에 한글을 쓰기 위해 인코딩 방식을 파라미터로 지정(utf-8)
  • 두 번째 with 블록은 동일한 파일을 대상으로 읽기 모드와 인코딩 파라미터를 이용해 파일 객체 생성
    • read() 함수 호출 시 파일에 저장된 한글 텍스트 출력

파일 시스템

  • 파일과 디렉터리를 조작하고 경로를 설정할 수 있는 os, glob 모듈
    • 프로그램을 이용해 파일로부터 자료를 읽고, 쓰기 위해서는 운영체제에서 지원하는 파일 시스템의 도움이 필요
      • 예: 특정 파일의 자료를 읽기 위해 파일이 저장된 디렉터리(폴더) 위치와 경로 지정
      • 자료를 파일에 쓰기 위해 해당 파일이 만들어질 디렉터리를 만들고 이동하는 작업 등이 필요

파일, 디렉터리 관련 함수

  • 파일과 디렉터리를 조작하고 처리하는 관련 함수

os 모듈

  • os.getcwd()
    • 현재 작업 디렉터리의 위치를 반환
  • os.mkdir(path)
    • 해당 디렉터리를 생성
  • os.rmdir(path)
    • 해당 디렉터리를 삭제
    • 내용이 있는 디렉터리 삭제 불가

파일 포인터의 위치

  • 파일을 읽을 때, 파일 포인터(file pointer, 즉 읽는 위치)가 중요
  • f.readlines()를 호출하면 파일 전체를 한 번에 읽어서 리스트로 반환
    • 이때 파일 포인터는 파일 끝(EOF, End Of File)으로 이동
  • 그 후에 f.read()를 호출하면, 이미 파일 끝에 있으므로 읽을 내용이 없어서 빈 문자열이 반환되니 주의

코드 흐름 예시

f = open("test.txt", mode='r')

# 파일 전체를 읽어서 리스트로 반환, 포인터는 EOF로 이동
f_readlines = f.readlines()

# 이 시점에 f.read()를 호출하면, 읽을 내용이 없음
print(f.read())  # 빈 문자열 출력

해결 방법

1. 파일 포인터를 처음으로 되돌리기

  • f.seek(0)을 사용해서 파일 포인터를 파일의 처음으로 옮길 수 있음
f = open("test.txt", mode='r')
f_readlines = f.readlines()

# 파일 포인터를 처음으로 이동
f.seek(0)

print(f.read())  # 이제 전체 내용이 출력됨

2. 파일을 새로 열기

  • f.readlines()f.read()를 각각 새로 연 파일에서 사용해도 됨

결론

  • f.readlines()f.read()는 파일 포인터를 EOF로 이동시킴
  • EOF에서는 더 이상 읽을 내용이 없으므로, 추가적인 read()는 빈 문자열을 반환
  • 파일 포인터를 seek(0)으로 이동시키면 다시 읽을 수 있음

참고

파일을 다 읽고 나면 포인터가 끝에 가 있으니,
다시 읽으려면 항상 포인터를 처음으로 되돌려야 한다는 점을 기억하세요!


정규 표현식

  • Web, SNS(Social Networking Service)에서 수집한 자료 → 대부분 미가공 상태로 수집
    • 따라서 필요한 문자열을 적절하게 자르고, 교체하고, 추출하는 작업이 빈번하게 발생 == 정제, 필터링
dir/p *.*

UNIX → LINUX → CPM → DoS 운영체제
UNIX의 프로그래밍 언어가 C
: C 언어는 유닉스 운영체제의 핵심 부분을 구현하는 데 사용되었고, 유닉스는 C 언어를 대표하는 운영체제임

  • 정규 표현식(Regular Expression)
    • 특정한 규칙을 가진 문자열의 집합을 표현하는데 사용하는 형식 언어
    • 텍스트 편집기와 프로그래밍 언어에서 문자열의 검색과 치환을 위한 용도로 사용
      • 자연어를 대상으로 원하는 단어만 추출 → 단어가 되기 위한 일정한 패턴(Pattern) 존재 → 이러한 매턴을 표준화된 텍스트 형식으로 나타낸 것을 정규 표현식, 이때 텍스트를 구성하는 하나의 문자를 메타문자라고 함

메타문자

  • 메타문자(Meta characters)
    • 정규표현식에서 일정한 의미를 가지고 있는 특수문자

  • 예: findall('^test', st2)
    • ^test : test로 시작하는 문자열
  • 역슬래쉬(\)로 시작하는 이스케이프 문자를 이용하여 정규표현식의 메타문자로 사용할 수 있음

정규 표현식 모듈(라이브러리)

  • re 모듈
    • 기본 라이브러리라 설치할 필요 없음
    • 메타문자를 이용하여 매턴(정규 표현식)을 만들고, 이러한 매턴을 특정 문자열에 적용하여 문자열을 처리할 수 있는 파이썬 모듈


문자열 처리

[ *\$ ]

  • 메타문자를 이용하여 패턴(정규 표현식) 작성

문자열 찾기

  • findall() 함수

    • 패턴과 일치하는 문자열을 찾음
    • 패턴과 일치되는 문자열이 있으면 해당 문자열을 리스트(list) 자료구조로 반환
    • 일치하는 문자열이 없으면 빈 리스트([])로 반환
    • 파라미터
      1. pattern: 메타문자를 이용하여 작성한 정규 표현식
      2. string: 처리할 문자열
      3. flags=0: 기본값 O 을 가지고 있기 때문에 일반적으로 생략
  • 형식

import re
re.findall(pattern, string[, flags=0])

[ ]: 생략 가능의 뜻

※ 인수와 매개변수 차이
: 함수를 호출하는 곳이면 인수, 함수를 정의하는 곳이면 매개변수

  • 예시
import re # 모듈 추가 - 방법1
from re import findall # 모듈 추가 - 방법2

st1 = "1234 abc흥길동 ABC_555_6 이사도시"

# (1) 숫자 찾기
print(findall("1234", st1))
print(findall("[0-9]", st1))
print(findall("[0-9]{3}", st1))
print(findall("[0-9]{3,}", st1))
print(findall("\\d{3,}", st1))

# (2) 문자열 찾기
print(findall("[가-힣]{3,}", st1))
print(findall("[a-z]{3}", st1))
print(findall("[a-z|A-Z]{3}", st1))

# (3) 특정 위치의 문자열 찾기
st2 = "test1abcABC 123mbc 45test"

# 접두어/접미어
print(findall("^test", st2)) # 접두어
print(findall("st$", st2)) # 접미어

# 종료 문자 찾기: abc, mbc
print(findall(".bc", st2))

# 시작 문자 찾기
print(findall("t.", st2))

# (4) 단어 찾기(\\w) - 한글+영문+숫자
st3 = "test^홍길동 abc 대한*민국 123$tbc"
words = findall("\\w{3,}", st3)
print(words)

# (5) 문자열 제외: x+(x가 1개 이상 반복)
print(findall("[^^*$]+", st3)) # 특수문자 제외

(1) 숫자 찾기

  • 숫자를 찾을 수 있는 다양한 매턴을 문자열에 적용하여 때턴과 일치하는 문자열을 리스트로 반환
    • [0-9]: 숫자 1개와 일치되는 패턴
      • \\d로도 쓸 수 있음
    • [0-9] {3}: 숫자가 3개 연속된 패턴
      • {}: 반복을 의미하는 {} 메타문자
    • [0-9] {3,}: 숫자가 3개 이상 연속된 경우
      • 숫자 뒤에 콤마(,)를 붙임

(2) 문자열 찾기

  • 한글이나 영문자 등의 문자열을 찾는 매턴을 적용 → 패턴과 일치하는 문자열을 리스트로 반환
    • [가-휠J{3,}: 한글 3자 이상 연속된 패턴
    • [a-z|A-Z]{3}: 영문 소문자 또는 대문자가 3개 연속된 패턴

(3) 특정 위치의 문자열 찾기

  • 문장의 시작이나 끝 지점 또는 특정 문자로 시작하거나 특정 문자로 끝나는 문자열을 찾는 패턴
    • ^test: 메타문자 ^ 이용해 문자열에서 접두어 test 찾는 방법
    • st$: 메타문자 $ 이용해 문자열의 접미어 st 찾는 방법
    • .bc: 메타문자 . 이용해 3개 문자로 구성된 문자열 중 bc로 끝나는 문자열 찾는 패턴
      • 메타문자 .: 문자 1개를 받을 수 있는 와일드카드 역할

(4) 단어 찾기(\\w)

  • 이스케이프 문자를 메타문자로 이용해 패턴 작성
    • \\w: 단어(word)를 인식하는 메타문자로 사용됨
      • 역슬레시를 하나 더 붙인 이유: 이스케이프 문자를 정규 표현식의 메타문자로 사용하기 위함
      • 패턴 앞부분에 r 문자를 붙여도 됨
    • \\w{3,}: 한글, 영문자, 숫자 중 하나가 3개 이상 연속된 것을 단어로 찾기 위한 패턴
      • 특수문자는 제외!

(5) 문자열 제외([^])

  • 문자열에서 특정 문자 또는 문자열을 제외시킬 때 사용되는 패턴
    • [^^*$]+: [^], + 메타문자를 이용하여 특수문자(^, *, $)를 문자열에서 제거하는 패턴
      • [^] 메타문자: ^ 다음에 오는 문자를 제외시키는 역할
      • +: 기호 앞에 오는 문자가 1개 이상 연속되는 패턴의 의미
  • 텍스트나 자연어를 전처리하는 용도로 많이 이용

파이썬에서 단어 문자에 포함되는 것
영문자: a-z, A-Z
숫자: 0-9
언더스코어: _
한글: 가-힣
단어 문자에 포함되지 않는 것
공백:
특수문자: !@#$%^^&*()-+=[]{}|;:'"<>,.?/
기타: 탭, 줄바꿈 등
따라서 \\w 패턴에서 인식하는 것은 '단어 문자'만 → *는 단어 문자가 아닌 그냥 문자

문자열 검사

  • match()

    • 문자열이 패턴과 일치되는지의 여부를 검사
    • 주어진 문자열에서 패턴과 일치하는 문자열이 있으면 객체(re.Match 0bject) 반환, 일치하는 문자열이 없으면 None 반환
    • 파라미터
      • pattern: 메타문자를 이용하여 작성한 정규 표현식
      • string: 처리할 문자열
      • flags=0
    • 주민 번호 또는 email 양식 위배 여부 검증 시 사용
  • 형식

import re
re.match(pattern,string[, flags=0])
  • 예시
from re import match # re 모듈 import

# (1) 패턴과 일치된 경우
jumin = "123456-3234567"
result = match("[0-9]{6}-[1-4][0-9]{6}", jumin)
print(result)  # re.Match object

if result: # object
    print("주민번호 일치")
else: # null
    print("잘못된 주민번호")

# (2) 패턴과 불일치된 경우
jumin = "123456-5234567"
result = match("[0-9]{6}-[1-4][0-9]{6}", jumin)
print(result)  # None

if result: # object
    print("주민번호 일치")
else: # null
    print("잘못된 주민번호")

(1) 패턴과 일치된 경우

  • [0-9]{6}-[1-4][0-9]{6}
    • 주민번호 13 자리 숫자를 검사하기 위해 하이픈(-)을 기준으로 앞부분 6자리 숫자,하이픈(-) 다음에 오는 성별 1자리 숫자, 그리고 나머지 6개의 숫자를 메타문자를 이용해 정규 표현식으로 지정
  • jumin 변수의 문자열 객체가 패턴과 일치하면 match 클래스의 객체를 반환 → re.Match object
  • 객체를 반환 받은 result 변수를 if문에서 사용할 경우 비교 판단하여 if문의 실행문을 실행
    • 객체가 반환되면 True
    • 객체가 반환되지 않으면 False

(2) 패턴과 불일치된 경우

  • 성별 1자리에 올 수 있는 숫자는 1에서 4 사이의 정수 1개가 올 수 있는 패턴으로 지정되어 있음 → 패턴과 일치되지 않은 주민번호로 인식되면 None 반환

정규표현식 이해하기

profile
2 B R 0 2 B

0개의 댓글