2012-06-06 5 views
3

일반 파일을 읽는 데 어려움을 겪고 있습니다. 현재 내가 겪고있는 문제는 pdfs가 BOM을 포함한 돌연변이 된 utf-8을 기반으로한다는 점입니다. 내 응용 프로그램 내에서 ascii 입력이 필요한 Snowball 형태소 분석 알고리즘을 사용하고 있습니다. utf-8로 해결하기 위해 오류를 가져 오는 것을 포함하는 많은 주제가 있지만, Snowball 알고리즘으로 보내지는 않으며, 아스키가 최종 결과를 원한다는 사실을 고려하지 않아야합니다. 현재 사용중인 파일은 표준 ANSI 인코딩을 사용하는 메모장 파일입니다. 내가 얻을 특정 오류 메시지는 이것이다 : 나의 이해는 파이썬 내에서 간단하게 발생하고 이런 식으로 내가 어떤 BOM 또는 특수 문자를 무시하는 어떤 비 ASCII 문자를 건너 것 인수를 무시 포함되었다 UnicodeDecodeError, Snowball 스니 밍 알고리즘 (Snowball stemming algorithm) (파이썬에서 사용)

File "C:\Users\svictoroff\Desktop\Alleyoop\Python_Scripts\Keywords.py", line 38, in Map_Sentence_To_Keywords 
    Word = Word.encode('ascii', 'ignore') 
UnicodeDecodeError: 'ascii' codec can't decode byte 0x96 in position 0: ordinal not in range(128) 

, 그러나 이것은 분명하지 않습니다. 나는 또한 문제가 문자가 제거 될 것으로 기대 문자열의 앞에 일반적인 비 욕심이 아닌 문자 정규식 제거를 포함하여

def Map_Sentence_To_Keywords(Sentence, Keywords): 
    '''Takes in a sentence and a list of Keywords, returns a tuple where the 
    first element is the sentence, and the second element is a set of 
    all keywords appearing in the sentence. Uses Snowball algorithm''' 
    Equivalence = stem.SnowballStemmer('english') 
    Found = [] 
    Sentence = re.sub(r'^(\W*?)(.*)(\n?)$', r'\2', Sentence) 
    Words = Sentence.split() 
    for Word in Words: 
     Word = Word.lower().strip() 
     Word = Word.encode('ascii', 'ignore') 
     Word = Equivalence.stem(Word) 
     Found.append(Word) 
    return (Sentence, Found) 

하지만, 다시는 그렇지 않다 :라는 실제 코드는 여기에있다. ascii 외에도 여러 가지 다른 인코딩을 시도했으며 엄격한 base64 인코딩이 작동하지만 내 응용 프로그램에는별로 적합하지 않습니다. 이 문제를 자동화 된 방법으로 해결하는 방법에 대한 아이디어가 있습니까?

Element의 초기 디코딩은 실패하지만 실제로 인코더로 전달 될 때 유니 코드 오류를 반환합니다.

for Element in Curriculum_Elements: 
     try: 
      Element = Element.decode('utf-8-sig') 
     except: 
      print Element 
     Curriculum_Tuples.append(Map_Sentence_To_Keywords(Element, Keywords)) 

def scraping(File): 
    '''Takes in txt file of curriculum, removes all newlines and returns that occur \ 
    after a lowercase character, then splits at all remaining newlines''' 
    Curriculum_Elements = [] 
    Document = open(File, 'rb').read() 
    Document = re.sub(r'(?<=[a-zA-Z,])\r?\n', ' ', Document) 
    Curriculum_Elements = Document.split('\r\n') 
    return Curriculum_Elements 

표시된 코드는 커리큘럼 요소를 생성합니다.

for Element in Curriculum_Elements: 
     try: 
      Element = unicode(Element, 'utf-8-sig', 'ignore') 
     except: 
      print Element 

이 유형 변환 해킹은 실제로 작동하지만 ASCII로 다시 변환하면 다소 불안합니다. 반환이 오류 :

Warning (from warnings module): 
    File "C:\Python27\lib\encodings\utf_8_sig.py", line 19 
    if input[:3] == codecs.BOM_UTF8: 
UnicodeWarning: Unicode equal comparison failed to convert both arguments to Unicode - interpreting them as being unequal 
+1

욕심이 없어야합니까? ''^ A^AHello, World! ''라고 가정 해보십시오.그런 다음 욕심이 없기 때문에 첫 번째 캡처에서''^ A''의 ** none **이 일치합니다. 그들은 두 번째 포획에서 끝나고, 따라서 당신의 치환 된 문자열에서 끝납니다. –

+0

좋은 지적이지만, 실제로 문제는 문자를 전혀 인식 할 수없는 경우입니다. –

답변

5

다음 ASCII로 그 인코딩 (비 ASCII 무시) 먼저 unicode 스트링으로 UTF-8 입력 복호화 시도. 이미 인코딩 된 문자열을 인코딩하는 것은 실제로 의미가 없습니다.


input = file.read() # Replace with your file input code... 
input = input.decode('utf-8-sig') # '-sig' handles BOM 

# Now isinstance(input, unicode) is True 

# ... 
Sentence = Sentence.encode('ascii', 'ignore') 

편집 후, 나는 이미 ASCII에서 그들을 인코딩하기 전에 문자열을 디코딩 시도했던 것을 알 수있다. 그러나 파일의 내용이 이미 조작 된 후 디코딩이 너무 늦게 시작된 것 같습니다. 모든 UTF-8 바이트가 문자 (일부 문자는 인코딩하는 데 몇 바이트가 소요됨)가 아니기 때문에 문제가 발생할 수 있습니다. 문자열을 ab의 시퀀스로 변환하는 인코딩을 생각해보십시오. 인코딩되지 않은 문자열에 아무 것도 없더라도 ab이 어디서나 볼 수 있기 때문에 디코딩 전에 조작하지 않으려합니다. UTF-8에서 같은 문제가 발생하지만 훨씬 미묘하기는하지만 대부분 바이트는 실제로 문자입니다. 내가 분할 전에 ASCII로 인코딩을 제안하지만

def scraping(File): 
    '''Takes in txt file of curriculum, removes all newlines and returns that occur \ 
    after a lowercase character, then splits at all remaining newlines''' 
    Curriculum_Elements = [] 
    Document = open(File, 'rb').read().decode('utf-8-sig') 
    Document = re.sub(r'(?<=[a-zA-Z,])\r?\n', ' ', Document) 
    Curriculum_Elements = Document.split('\r\n') 
    return Curriculum_Elements 

# ... 

for Element in Curriculum_Elements: 
    Curriculum_Tuples.append(Map_Sentence_To_Keywords(Element, Keywords)) 

원래 Map_Sentence_To_Keywords 기능은 단지 효율성/가독성을 향상시키기 위해, 수정없이 작동합니다 : 다른 작업을 수행하기 전에

그래서, 한 번 디코딩.

+0

이 함수에 문장이 전달되기 전에 문장이 이미 디코딩되었습니다. –

+0

그래서 문장은'unicode'의 인스턴스입니까? 그렇다면 오류가 발생하지 않아야합니다. 어쩌면 함수의 맨 위에 'assert isinstance (Sentence, unicode)'를 추가하여 재확인 할 수 있습니까? – Cameron

+0

디코드가 어떤 이유로 작동하지 않습니다. 편집하여이 오류에 관련 코드를 추가하십시오. –