2013-06-06 2 views
1

저는 epub 2를 파싱하는 파이썬 스크립트를 작성하고 있습니다. 그래서 단어, 문장 및 단락을 자신의 개체로 나눌 수 있도록 노력하고 있습니다 ... 단어와 단락을 사용할 수 있지만 문제는 문장에 있습니다. 왜냐하면 때때로 "..."이있을 것이기 때문입니다. 문장의 끝에서 구분 기호로 사용됩니다. 하지만 문제는 내가 문자를 파싱한다는 것이므로 ".", "!"또는 "?" 내 시스템은 문장의 끝으로 계산 ... 전 공백이나 문장 구분 기호인지 확인하기 위해 이전 문자를 읽을 수있는 복잡한 if 문을 작성하려고했지만 모든 시도는 작동하지 않습니다. 이것에 대한 조언은 크게 감사 할 것입니다. 내가 언급해야 할 한가지는이 시스템에서 작동하지 않기 때문에 정규 표현식을 사용하지도 않고 사용할 수도 없다는 것입니다.어떻게 파이썬 직렬 파서에서 문장의 끝을 결정합니까?

def add_until(self): 

    char_list = [] 
    end_sentence = False 

    for char in self.source: 

     if isinstance(char, Character) or isinstance(char, EntityRef): 
      char_list.append(char) 

      if len(char_list) >= 2 and char_list[-2].is_whitespace or len(char_list) >= 2 and char_list[-2].split_sent and char.is_whitespace or char.split_sent: 
        char_list.append(char) 


      if len(char_list) >= 2 and char_list[-2].is_whitespace and char.split_sent == False and char.is_whitespace == False: 
       char_list.pop() # pop's the last space off because it should be part of the next sentience. 

답변

1

당신은 욕심 문자열 일치를 사용할 필요가 : 여기

내가 사용하려고했던 코드입니다. 일반적으로, 이런 종류의 일을하기 위해서, 나는 문자열을 청크로 슬라이스하고 필요한 경우 길이를 줄이면서 문자열을 반복합니다. 귀하의 예제와 함께 :

source = """This is a sentence... This is a second sentence. 
     Is this a sentence? Sure it is!!!""" 

stop = ('...', '.', '?', '!', '!!!') 

i = 0 
M = max(len(s) for s in stop) 
L = len(source) 

while i <= L: 
    m = M 
    while m > 0: 
     chunk = source[i:i + m] 
     if chunk in stop: 
      print("end of sentence with: %s" % chunk) 
      break 
     m -= 1 
    else: 
     m = 1 
    i += m 

이 출력 :

end of sentence with: ... 
end of sentence with: . 
end of sentence with: ? 
end of sentence with: !!! 

당신은 또한 확인 할 수 있습니다 경우 "문장의 끝에"토큰이 대문자 후 첫 번째 공백이 아닌 문자 (또는 숫자) . 프리 프로세서의

편집

샘플 예를 들어, 비 필요한 공백을 제거하기위한 :

def read(source): 
    had_blank = False 
    for char in source: 
     if char == ' ': 
      had_blank = True 
     else: 
      if had_blank and not char in '.?!': 
       yield ' ' 
       yield char 
       had_blank = False 
      else: 
       yield char 

그것을 사용 : 당신의 응답을

>>> source = "Sentence1 .. . word1 word2. . . word other_word . . ." 
>>> ''.join(c for c in read(source)) 
'Sentence1... word1 word2... word other_word...' 
+0

뛰어난 덕분에 ... 나는이 좋아 솔루션 ...이 일을하지 않을 수도 있지만 한 가지가 있습니다 ... 나는 각 기간 사이에 공백이있는 타원으로 실행했습니다. 정지 목록? –

+0

그렇습니다. 그러나 가능한 모든 경우 (예 : "..", ".. ..", ".."등)를 숨기려면 많은 "정지"토큰이 필요합니다.). 한 번에 한 문자 씩 출력하는 "reader"기능을 사용하고 공백을 표시하는 방법도 있습니다. – michaelmeyer

+0

사실입니다. 그게 실제로 어떻게 보이나요? 당신은 somevar.next()를 할 수 있도록 소스를 생성기에 넣으시겠습니까? 아니면 공간이나 문자 또는 감정이 나쁘면 테스트 할 수 있습니까? –

관련 문제