티스토리 뷰

728x90
파이썬으로 pdf -> text 추출을 하기 위해 공부한 내용을 정리한다. 처음부터 정리했기 때문에 데이터 정제를 하는 사람이라면
꼭 참고하여 도움이 되길...

 

처음 인지해야 할 것! 

 

☆ 처음 들어온 값이 리스트인지 스트링 타입인지 알 것 

  - 이걸 알고 있는 상태로 전체 로직을 구성해야한다.

 

 

☆ 들어오는 인풋 값과 나가는 아웃풋이 무엇으로 나가는지 생각해야 한다.(위와 같은 내용)

  - 아무것도 모를 때 신경을 쓰지 않았는데 그러다 보니 타입 오류 & 정규식이 먹지 않는 현상이 발생한다.

 

 

☆ 네이밍 신경 쓰기

  - answer, result, sentence 이런 것만 돌리지 말고 한눈에 이해할 수 있는 변수명 사용하기

 

 

☆ 작동이 되지 않는다면 print() 함수를 이용하여 하나하나 어떤 값이 들어오는지 찍어본다.

 

☆ 정규식을 적용하려면 문자열로 받아야 한다!!!!!!!! 리스트 아님!

1. 리스트

  - pdf를 담고 있는 길이를 구하기 위해 사용한다. 

  - 한 문장 한 문장씩 보려는 의도로 리스트를 사용한다.

  - 리스트 타입에 대하여 for문 처리를 하고 정규식을 사용한다.

  - 리스트를 이용하여 엑셀화를 진행한다. 

 

2. 스트링(String)

  - 스트링 타입일 때 정규식을 적용해야 한다.

  - 스트링 타입을 리스트로 바꿔주려면 a = [ ]라는 값을 담을 빈 배열을 생성해주고, 

    a.append(s)로 값을 담는다. 

 

3. 정규식

  - 병기 문자:각종 언어를 표기할 때 보조적인 언어를 옆에 병기하는 것을 말한다.

#병기문자 삭제
def deleteAssistantWord(text): #스트링 들어옴
    result = []
    delete_word = re.sub(r'[\(]+[\w\s]+[\)]+','',text) #스트링 병기문자를 삭제하고 그 값을 replace_word에 스트링으로 담김
    result.append(delete_word)  #replace_word스트링을 리스트형식으로 word에 담아줌
    return result

 

 

- 한 문장에 영어, 숫자 30% 이상인 경우 제외 함수

#한 문장에 영어,숫자 30% 이상인 경우 제외
def exclueEngNum30(text):
    enNum = re.compile('[a-zA-Z0-9]*') #영어숫자만 선택
    sentence = re.compile('.*') #전체문장 선택
    m=enNum.findall(text)
    s=sentence.findall(text)

    if 31 > (len(m) / len(s) * 100):    #퍼센트구하기
        return True
    else:
        return False

 

- 30~10 어절 이상 80음절 이하일 때 선택하는 함수

# 30~10 어절과 80이하 음절 선택
def chooseWord(text):  # 문자열 단위로 입력받음
    if 31 > len(text.split(' ')) > 9 and 81 > len(text):
        return text

 

4. compile. search, match, sub, findall 

 

 

0. compile파이썬에게 전해주는 역할, 찾고자 하는 패턴이 빈번한 경우에는 미리 컴파일해놓고 사용하면 속도와 편의성면에서 유리

sentence = '안녕하세요 테스트 입니다.'
test = re.compile('[a-z가-힣\[\]])
result = test.search(sentence)
print(result)

 

 

 

1. search는 전체 문자열에서 정규식을 찾는다. 

  - search와 일치하는 문자열에서 index 값과 & 일치 문자를 찾고, 오브젝트 형식으로 뱉는다.

  - index값을 찾아서 [ :찾은 index값 ] + '넣고 싶은 내용' + [찾은 index: ]이렇게 해서 문자를 추가할 수 있다.

  - sub은 문자열 ' ' 형태로 변환하기 때문에 추가하려면 search로 추가하는 방법을 써야 한다.

 

answer = []
sentence = '안녕하세요 코딩 테스트 입니다.'
test = re.compile('안녕하세요') #안녕하세요 라는 문자열 선택 정규식
result = test.search(sentence) # sentence에 값을 test로 컴파일한 정규식을 통해서 search하는데 그 값을 result에 담겠다.
answer.append(result) # result값을 answer에 담겠다.

결과

결과: 0:5index에 있는 '안녕하세요'문자열과 매치 되었다.

 

✈︎

search로 찾은 실제 결과 문자열을 얻기 위해서는 group() 함수를 사용한다.
sentence = '안녕하세요 코딩 테스트 입니다.'
test = re.compile('안녕하세요') #안녕하세요 라는 문자열 선택 정규식
result = test.search(sentence) # sentence에 값을 test로 컴파일한 정규식을 통해서 search하는데 그 값을 result에 담겠다.
answer = result.group() # result값을 group()함수를 사용하여 문자열 값을 출력
print(answer)

 

 

 

 

2. match는 앞 문자열부터 정규식과 일치하는 문자열을 찾는다.

  - 많이 사용하진 않음

  - 정확한 일치를 요구할 때 사용한다.

  -ex: 문자열 'apple'과 'happy'에

    [a]를 찾고 싶어, 정규식[a]과 match를 사용하면, apple의 a는 선택되고, happy는 선택되지 않는다.

import re

answer = []
sentence = '안녕하세요 코딩 테스트 입니다.'
test = re.compile('코딩') #코딩 이라는 문자열 선택 정규식
result = test.match(sentence) # sentence에 값을 test로 컴파일한 정규식을 통해서 search하는데 그 값을 result에 담겠다.
answer.append(result) # result값을 answer에 담겠다.
print(answer)

결과

결과: match는 앞 문자열부터 일치여부를 찾기 때문에 중간에 나온 '코딩'을 찾을 수 없다고 뜬다. 

-> compile에 '안녕하세요' 넣으면 search와 같은 값이 나온다.(아래 이미지 참고)

match 결과

 

 

3. sub 문자열에서 정규 표현식과 일치하는 부분에 대해서 다른 문자열로 대체한다.

  - 문자열 대체, 삭제 역할로 사용한다.

  - ('정규식', '대체할 값', 값을 담고 있는 변수) 이렇게 사용한다.

  - sub을 이용하여 ('정규식', '' , 자료를 담고있는 변수) 이렇게 주면 대체 문자열이 없는 ''이므로 

    정규식과 일치하는 문자가 삭제된다.

  - sub은 문자열 ' 들어있는 값 ' 형태로 변환한다. search의 변환과는 다른 개념.

 

answer = [] #값을 담을 빈배열 생성

for sentence in line:
        m = re.compile('([\d]+[\s]+)|([\(]+[\w\s]+[\)]+)') # 숫자+\t시작 + ( )안에 있는거 지우는 정규식
        result = re.sub(m, '', sentence).strip() #result = 정제된 결과물 스트링 형식
        answer.append(result) #result의 값이 스트링이므로 이것을 anwer 배열에 더해서 아래 엑셀 만들 때 사용 
        
        
        #아래의 엑셀로 만드는 라이브러리에 for문으로 하나하나 담아주기
        
        wb = Workbook(write_only=True)
        ws = wb.create_sheet('test')
        ws.append(['parsing sentences_kor'])


        column = []
        for i in answer:
            column.append(i)
        print(column)
        ws.append(column)
        wb.save

 

 

 

 

 

4. findall

  - 문자열에서 정규 표현식과 매치되는 모든 경우의 문자열을 찾아서 리스트로 리턴한다.

  - 매치되는 문자열이 없다면 빈 리스트가 리턴된다.

  - 리스트 형태로 바꿔주기 때문에 포스팅 맨 상단에 작성한 어떤 값으로 들어오고 변환되는지 인지하는 게 중요!!!

 

 

 

 

 

 

무작정 하려고 했는데 그렇게 무지 성으로 로직을 짜다 보니 빙빙 돌고 오류에 막혀 시간 날리기 일쑤였다.

내가 위에서 설명한 것과 같이 들어오는 값이 스트링인지 리스트인지에 따라 search, match, findall, sub 등을 잘 사용하고 

print로 값을 계속해서 찍어보는 것이 중요하다!!

 

 

다들 데이터 파싱 파이팅~!

 

 

 

728x90
댓글
250x250
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday