파이썬 파일에서 문자 읽기


102

텍스트 파일에는 "I do n't like this"라는 문자열이 있습니다.

하지만 문자열로 읽어 오면 "I don \ xe2 \ x80 \ x98t like this"가됩니다. \ u2018이 " '"의 유니 코드 표현임을 이해합니다. 나는 사용한다

f1 = open (file1, "r")
text = f1.read()

읽기 명령.

자, 문자열을 읽을 때 "I don \ xe2 \ x80 \ x98t like this like"대신 "I do n't like this"가되도록 문자열을 읽을 수 있습니까?

두 번째 편집 : 일부 사람들이이 문제를 해결하기 위해 매핑을 사용하는 것을 보았지만 실제로 이러한 종류의 ANSI를 유니 코드로 (또는 그 반대로) 변환하는 기본 제공 변환이 없습니까?


일부 의견 : 일부 사람들이이 문제를 해결하기 위해 매핑을 사용하는 것을 보았습니다. 그러나 실제로 이러한 종류의 ANSI를 유니 코드로 (또는 그 반대로) 변환하는 기본 제공 변환이 없습니까? 감사!
Graviton

수십만 개의 유니 코드 코드 포인트가 있기 때문에 그렇지 않습니다. 어떤 ASCII 문자에 매핑되어야 하는지를 어떻게 결정합니까?
John Millikin

2
btw, 텍스트 파일이 손상되었습니다! U + 2018은 아포스트로피가 아니라 "왼쪽 단일 따옴표"입니다 (가장 일반적으로 U + 0027).

존, 당신의 의견은 적어도 일반적인 의미에서 잘못되었습니다. iconv lib를 사용하여 유니 코드 문자를 ascii로 음역 할 수 있습니다 (로케일에 따라 다름. $ python -c 'print u "\ u2018".encode ( "utf-8")'| iconv -t 'ascii // translit'| xxd 0000000 : 270a

문제는 UNICODE를 ASCII로 변환해야한다는 것입니다.
hasen

답변:


157

참조 : http://docs.python.org/howto/unicode

따라서 파일에서 유니 코드를 읽는 것은 간단합니다.

import codecs
with codecs.open('unicode.rst', encoding='utf-8') as f:
    for line in f:
        print repr(line)

또한 업데이트 모드에서 파일을 열고 읽고 쓸 수 있습니다.

with codecs.open('test', encoding='utf-8', mode='w+') as f:
    f.write(u'\u4500 blah blah blah\n')
    f.seek(0)
    print repr(f.readline()[:1])

편집 : 의도 한 목표는 파일을 Python의 문자열로 올바르게 읽을 수 있다는 것입니다. 유니 코드에서 ASCII 문자열로 변환하려는 경우 유니 코드 문자가 반드시 ASCII로 존재하는 것은 아니기 때문에 실제로 그렇게하는 직접적인 방법은 없습니다.

ASCII 문자열로 변환하려는 경우 다음 중 하나를 시도하십시오.

  1. 이 특정 예제와 같은 몇 가지 특수한 경우 만 처리하려는 경우 특정 유니 코드 문자를 ASCII 등가 문자로 바꿉니다.

  2. unicodedata모듈 normalize()string.encode()방법을 사용하여 가능한 한 다음으로 가장 가까운 ASCII로 변환 하십시오 ( https://web.archive.org/web/20090228203858/http://techxplorer.com/2006/07/18/converting- 참조). unicode-to-ascii-using-python ) :

    >>> teststr
    u'I don\xe2\x80\x98t like this'
    >>> unicodedata.normalize('NFKD', teststr).encode('ascii', 'ignore')
    'I donat like this'
    

3
codecs모듈이 범용 줄 바꿈 모드를 제대로 처리하지 않습니다. io.open()대신 Python 2.7 이상에서 사용하십시오 ( open()Python 3에 내장 됨).
jfs

15

고려해야 할 몇 가지 사항이 있습니다.

\ u2018 문자는 Python에서 유니 코드 문자열 표현의 일부로 만 나타날 수 있습니다. 예를 들면 다음과 같습니다.

>>> text = u'‘'
>>> print repr(text)
u'\u2018'

이제 단순히 유니 코드 문자열을 예쁘게 인쇄하려면 유니 코드의 encode방법을 사용하십시오.

>>> text = u'I don\u2018t like this'
>>> print text.encode('utf-8')
I dont like this

모든 파일의 모든 행이 유니 코드로 읽히도록하려면 파일의 인코딩을 지정할 수있는 codecs.open대신 함수를 사용하는 것이 좋습니다 open.

>>> import codecs
>>> f1 = codecs.open(file1, "r", "utf-8")
>>> text = f1.read()
>>> print type(text)
<type 'unicode'>
>>> print text.encode('utf-8')
I dont like this

6

하지만 실제로는 "이것이 마음에 들지 않습니다"가 아니라 "이것이 마음에 들지 않습니다"가 아닙니다. 문자 u '\ u2018'은 " '"와 완전히 다른 문자입니다 (그리고 시각적으로'` '에 더 많이 대응해야 함).

인코딩 된 유니 코드를 일반 ASCII로 변환하려는 경우 ASCII로 변환하려는 유니 코드 구두점 매핑을 유지할 수 있습니다.

punctuation = {
  u'\u2018': "'",
  u'\u2019': "'",
}
for src, dest in punctuation.iteritems():
  text = text.replace(src, dest)

그러나 unicode 에는 문장 부호 문자 가 엄청나게 많지만 읽고있는 문서를 만드는 응용 프로그램에서 실제로 사용되는 문장 부호 중 몇 개만 믿을 수 있다고 생각합니다.


1
실제로, dict 맵 유니 코드 서수를 유니 코드 서수 ({0x2018 : 0x27, 0x2019 : 0x27})로 만들면 전체 dict를 text.translate ()에 전달하여 한 번에 모든 바꾸기를 수행 할 수 있습니다.
Thomas Wouters

5

python 3 read 메소드를 사용하여 인코딩 된 텍스트 파일을 읽을 수도 있습니다.

f = open (file.txt, 'r', encoding='utf-8')
text = f.read()
f.close()

이 변형을 사용하면 추가 라이브러리를 가져올 필요가 없습니다.


3

텍스트 파일이 손상되었다는 사실을 제쳐두고 (U + 2018은 아포스트로피가 아닌 왼쪽 인용 부호입니다) : iconv를 사용하여 유니 코드 문자를 ascii로 음역 할 수 있습니다.

모듈이 더 이상 지원되지 않는 것 같고 이에 대한 표준 홈페이지를 찾을 수 없기 때문에 "iconvcodec"을 검색해야합니다.

>>> import iconvcodec
>>> from locale import setlocale, LC_ALL
>>> setlocale(LC_ALL, '')
>>> u'\u2018'.encode('ascii//translit')
"'"

또는 iconv명령 줄 유틸리티를 사용 하여 파일을 정리할 수 있습니다.

$ xxd foo
0000000: e280 980a                                ....
$ iconv -t 'ascii//translit' foo | xxd
0000000: 270a                                     '.

2

어떤 식 으로든 유니 코드 이스케이프 문자가있는 유니 코드가 아닌 문자열이있을 가능성이 있습니다. 예 :

>>> print repr(text)
'I don\\u2018t like this'

이것은 실제로 전에 한 번 나에게 일어났습니다. unicode_escape코덱을 사용 하여 문자열을 유니 코드로 디코딩 한 다음 원하는 형식으로 인코딩 할 수 있습니다.

>>> uni = text.decode('unicode_escape')
>>> print type(uni)
<type 'unicode'>
>>> print uni.encode('utf-8')
I dont like this

1

이것은 파이썬 방식으로 유니 코드로 인코딩 된 문자열을 보여줍니다. 하지만 화면에 문자열을 인쇄하거나 문제없이 새 파일에 쓸 수 있어야한다고 생각합니다.

>>> test = u"I don\u2018t like this"
>>> test
u'I don\u2018t like this'
>>> print test
I dont like this

1

실제로 U + 2018은 특수 문자 '. 원하는 경우 다음 코드를 사용하여 해당 문자의 인스턴스를 U + 0027로 변환 할 수 있습니다.

text = text.replace (u"\u2018", "'")

또한 파일을 작성하기 위해 무엇을 사용하고 있습니까? f1.read()다음과 같은 문자열을 반환해야합니다.

'I don\xe2\x80\x98t like this'

문자열을 반환하는 경우 파일이 잘못 기록 된 것입니다.

'I don\u2018t like this'

죄송합니다! 말씀하신대로 'I don \ xe2 \ x80 \ x98t like this'를 반환합니다.
Graviton

당신이보고있는 'I don \ xe2 \ x80 \ x98t like this'는 파이썬이 str이라고 부르는 것입니다. 파이썬의 유니 코드 인스턴스 인 u'I don \ u2018t like this '의 utf-8 인코딩으로 보입니다. 전자에서는 .decode ( 'utf-8'), 후자에서는 .encode ( 'utf-8')을 호출 해보십시오.
Logan

@hop : 죄송합니다. ord ()는 16 진수 대신 십진수를 반환합니다. 잡아 주셔서 감사합니다.
John Millikin
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.