2011-07-29 2 views
1

나는 한 세트의 키워드를 검색해야하는 수많은 PDF 파일을 가지고있다. 키워드가있는 정확한 행을 추출해야합니다. 먼저 xpdf의 pdf2text를 사용하여 파일을 PDF로 변환했습니다. (시도했지만 solr하지만 내 요구 사항에 맞게 출력/스키마를 조정하는 힘든 시간을 보냈습니다).줄 바꿈을 제거하여 파이썬에서 문자열을 검색하지만 문자열이 발견 된 정확한 줄을 반환하는 방법은 무엇입니까?

import sys 

file_name = sys.argv[1] 
searched_string = sys.argv[2] 
result = [(line_number+1, line) for line_number, line in enumerate(open(file_name)) if searched_string.lower() in line.lower()] 

#print result 

for each in result: 
    print each[0], each[1] 

ThinkCode : ~ $ 파이썬 find_string.py하시면 sample.txt "문자열 추출"

나는이 함께이 문제입니다 검색 문자열의 끝으로 깨진 경우에 줄 :

큰 이진 파일을 인덱싱하려면 크기 제한을 변경해야합니다. 문자열

추출 제가 위에서 제시 한 코드를 사용하는 경우

내가 '문자열 추출'을 검색하고 있다면,이 키워드를 그리워하는 일반적인 문제입니다. 텍스트 파일의 사본 2 개 (줄을 추출하기 위해 키워드를 검색하기위한 것이고 줄 바꿈을 제거하고 키워드가 2를 가로 지르는 경우를 제거하기위한 키워드를 찾는 것에 대한 것)없이 이것을 달성하는 가장 효율적인 방법은 무엇입니까? 윤곽).

많은 감사를드립니다!

답변

1

참고 : 코드가없는 몇 가지 고려 사항이 있지만 의견보다는 대답에 속한다고 생각합니다.

제 아이디어는 첫 번째 키워드 만 검색하는 것입니다. 일치하는 항목이 있으면 두 번째 항목을 검색하십시오. 이렇게하면 줄 끝에서 일치하는 항목이 발견되면 다음 줄을 고려하여 처음부터 일치하는 항목이있는 경우에만 줄 연결을 수행 할 수 있습니다 *.

편집 :

간단한 예제를 코딩하고 다른 알고리즘을 사용하여 종료;

def iterwords(fh): 
    for number, line in enumerate(fh): 
     for word in re.split(r'\s+', line.strip()): 
      yield number, word 

그것은 파일 핸들러를 반복 실행하고 파일의 각 단어에 대한 (LINE_NUMBER, 워드) 튜플을 생성합니다 뒤에 기본 개념은이 코드입니다.

이후에 쉽게 일치됩니다. 내 구현 as a gist on github을 찾을 수 있습니다. 다음과 같이 실행할 수 있습니다 :

python search.py 'multi word search string' file.txt 

링크 된 코드를 하나의 주요 관심사, 나는 성능과 복잡성을 이유로 해결 방법을 코딩하지 않았다 있습니다. 알아낼 수 있니? 은 (스포일러가 : 그 첫 번째 단어 파일에 연속으로 두 번 나타나는 문장을 검색하려고)

가 * 내가 내 자신에 어떤 테스트를 수행하지 못했지만, this articlepython wiki 제안하는 문자열 연결입니다 python에서 그렇게 효율적이지는 않습니다 (실제로 정보가 어떻게되는지).

+0

좋아요! github 기여에 감사드립니다. 유일한 문제는 대소 문자를 구분하므로 같은 줄에 여러 키워드 인과 일치하는 키워드가있는 경우 두 번째 키워드는 다음 2 ~ 3 줄에 몇 가지 이유로 발견됩니다! 디버깅을 통해 내가 찾은 것을 알려줍니다! – ThinkCode

+0

새 개정판은 대소 문자를 구별하지 않습니다. 발견 한 버그와 관련하여 첫 번째 키워드와 일치하는 항목이 발견되면 반복기가 진행되고 연속 키워드 중 하나가 일치하지 않으면 현재 위치에서 검색이 계속됩니다 첫 번째 경기 이후 다음 단어가 아닙니다. – GaretJax

+0

사실, 각 키워드에 대한 텍스트를 추출하고 있으므로 여러 인스턴스가 문제가되지 않습니다! 대소 문자를 구별하기 위해 새 반복을 확인해야합니다. 유일한 다른 문제는 특수 기호입니다. 검색 문자열에 '(Search String'또는 'String')과 같은 기호가 있으면 'Search String'또는 'String'과 일치하지 않습니다. 그들을 정규식에서 떼어 내시겠습니까? 시간 내 주셔서 감사합니다. – ThinkCode

1

그 일을 더 나은 방법이있을 수 있지만, 내 제안은 line3 또는 비슷한으로 그들을을 연결, 두 줄 (의 그들 line1line2를 부르 자)에 복용에 의해 시작하고, 그 결과 행을 검색하는 것입니다.

그러면 line2line1으로 지정하고 line2을 새로 지정하고 과정을 반복하십시오.

+0

감사합니다. 그것은 (n-1) 연결 일 것입니다. 나는 접근법을 좋아하지만 가장 효율적인/비단뱀 접근법인가? 내가 더 나은 방법을 찾지 못한다면 나는 결국 당신의 접근 방식에 의지해야 할 것입니다. 감사! – ThinkCode

+0

그리고 키워드가 세 줄을 생성하면 어떻게 될까요? :) – GaretJax

+0

@GaretJax : 내 키워드는 3 단어로 제한되지만 좋은 생각입니다! – ThinkCode

0

사용 플래그 re.MULTILINE 당신의 표현식을 컴파일 할 때 : http://docs.python.org/library/re.html#re.MULTILINE

그런 (새로운 라인을 포함한) 모든 공백을 나타 내기 위해 \s를 사용합니다.

+0

're.MULTILINE'은 아무 관계가 없습니다. 그것은 단순히 정규식 패턴에서'^'와'$'의 동작을 변경합니다. 또한 여러 줄 바꿈이있는 경우 (제공된 예제와 같이) 단지'\ s'가 아니라'\ s +'여야합니다. – JAB

+0

re.compile ('search \ s * string', re.DOTALL)? – ThinkCode

+0

@ThinkCode :'re.DOTALL'은 검색 문자열에'.'을 사용하지 않으므로 필요하지 않습니다. 또한,'\ s *'보다는'\ s +'를 사용해야한다. 왜냐하면'\ s *'는'searchstring'을 매치시킬 것이기 때문이다. 실제로도 정규식 솔루션을 제안하는 생각을하고 있었지만, 어떤 이유로 라인 단위로 처리하는 것을 선호한다고 생각했습니다. – JAB

관련 문제