[python] 텍스트 파일에 유니 코드 텍스트를 작성 하시겠습니까?

Google 문서에서 데이터를 가져 와서 처리하고 파일에 씁니다 (결국 WordPress 페이지에 붙여 넣습니다).

비 ASCII 기호가 있습니다. HTML 소스에서 사용할 수있는 심볼로 안전하게 변환하려면 어떻게해야합니까?

현재 나는 모든 것을 유니 코드로 변환하고 파이썬 문자열로 모두 결합 한 다음 다음을 수행합니다.

import codecs
f = codecs.open('out.txt', mode="w", encoding="iso-8859-1")
f.write(all_html.encode("iso-8859-1", "replace"))

마지막 줄에 인코딩 오류가 있습니다.

UnicodeDecodeError : ‘ascii’코덱이 12286 위치에서 바이트 0xa0을 디코딩 할 수 없습니다 : 서 수가 범위 내에 있지 않습니다 (128)

부분 솔루션 :

이 파이썬은 오류없이 실행됩니다.

row = [unicode(x.strip()) if x is not None else u'' for x in row]
all_html = row[0] + "<br/>" + row[1]
f = open('out.txt', 'w')
f.write(all_html.encode("utf-8"))

그러나 실제 텍스트 파일을 열면 다음과 같은 많은 기호가 나타납니다.

Qur’an 

텍스트 파일이 아닌 다른 파일에 쓸 필요가 있습니까?



답변

객체를 처음 가져올 때 유니 코드 객체로 디코딩하고 필요에 따라 인코딩하는 방식으로 유니 코드 객체를 최대한 독점적으로 처리하십시오.

문자열이 실제로 유니 코드 객체 인 경우 파일에 쓰기 전에 유니 코드로 인코딩 된 문자열 객체로 변환해야합니다.

foo = u'Δ, Й, ק, ‎ م, ๗, あ, 叶, 葉, and 말.'
f = open('test', 'w')
f.write(foo.encode('utf8'))
f.close()

해당 파일을 다시 읽으면 유니 코드 객체로 디코딩 할 수있는 유니 코드로 인코딩 된 문자열이 나타납니다.

f = file('test', 'r')
print f.read().decode('utf8')


답변

Python 2.6 이상에서는 Python 3에서 기본값 ( builtin )을 사용할io.open()있습니다 .open()

import io

with io.open(filename, 'w', encoding=character_encoding) as file:
    file.write(unicode_text)

점진적으로 텍스트를 작성해야하는 경우 ( unicode_text.encode(character_encoding)여러 번 호출 할 필요가 없음) 더 편리 할 수 ​​있습니다 . codecs모듈 과 달리 , io모듈은 적절한 범용 줄 바꾸기를 지원합니다.


답변

유니 코드 문자열 처리는 이미 Python 3에서 표준화되었습니다.

  1. 문자는 메모리의 유니 코드 (32 비트)에 이미 저장되어 있습니다.
  2. utf-8로만 파일을 열면됩니다
    (32 비트 유니 코드에서 가변 바이트 길이의 utf-8 로의 변환은 메모리에서 파일로 자동 수행됩니다).

    out1 = "(嘉南大圳 ㄐㄧㄚ ㄋㄢˊ ㄉㄚˋ ㄗㄨㄣˋ )"
    fobj = open("t1.txt", "w", encoding="utf-8")
    fobj.write(out1)
    fobj.close()

답변

열린 codecs.open파일은 unicode데이터 를 가져 와서 인코딩 한 iso-8859-1후 파일에 쓰는 파일입니다. 그러나, 당신이 쓰려고하는 것은 아니다 unicode; 당신은 unicode그것을 iso-8859-1 자신의 것으로 받아들이고 인코딩합니다 . 이것이 unicode.encode메소드가하는 일이며, 유니 코드 문자열을 인코딩 한 결과는 바이트 스트링 ( str유형)입니다.

당신도 정상 사용해야 open()하고, 유니 코드를 직접, 또는 (일반적으로 더 나은 아이디어)을 사용 인코딩 codecs.open()하지 의 데이터를 직접 인코딩.


답변

서문 : 시청자가 작동합니까?

뷰어 / 편집기 / 터미널 (utf-8로 인코딩 된 파일과 상호 작용하고 있음)이 파일을 읽을 수 있는지 확인하십시오. 이것은 메모장과 같은 Windows 에서 자주 발생하는 문제입니다 .

텍스트 파일에 유니 코드 텍스트를 작성 하시겠습니까?

Python 2에서는 모듈 open에서 사용 io합니다 ( openPython 3 의 기본 제공 기능과 동일 ).

import io

모범 사례는 일반적 UTF-8으로 파일에 쓰는 데 사용합니다 (utf-8의 바이트 순서에 대해 걱정할 필요조차 없음).

encoding = 'utf-8'

utf-8은 가장 현대적이고 보편적으로 사용 가능한 인코딩입니다. 모든 웹 브라우저, 대부분의 텍스트 편집기 (문제가있는 경우 설정 참조) 및 대부분의 터미널 / 쉘에서 작동합니다.

Windows에서는 utf-16le메모장 (또는 다른 제한된 뷰어)에서 출력보기로 제한되어 있으면 시도해 볼 수 있습니다 .

encoding = 'utf-16le' # sorry, Windows users... :(

컨텍스트 관리자로 열고 유니 코드 문자를 작성하십시오.

with io.open(filename, 'w', encoding=encoding) as f:
    f.write(unicode_object)

많은 유니 코드 문자를 사용하는 예

다음은 가능한 모든 문자를 최대 3 비트 (4는 최대이지만 조금 멀어 질 것입니다)에서 디지털 표현 (정수)에서 인코딩 된 인쇄 가능 출력 (이름과 함께)과 매핑하는 예제입니다. 가능합니다 (이 파일을 파일에 넣으십시오 uni.py) :

from __future__ import print_function
import io
from unicodedata import name, category
from curses.ascii import controlnames
from collections import Counter

try: # use these if Python 2
    unicode_chr, range = unichr, xrange
except NameError: # Python 3
    unicode_chr = chr

exclude_categories = set(('Co', 'Cn'))
counts = Counter()
control_names = dict(enumerate(controlnames))
with io.open('unidata', 'w', encoding='utf-8') as f:
    for x in range((2**8)**3):
        try:
            char = unicode_chr(x)
        except ValueError:
            continue # can't map to unicode, try next x
        cat = category(char)
        counts.update((cat,))
        if cat in exclude_categories:
            continue # get rid of noise & greatly shorten result file
        try:
            uname = name(char)
        except ValueError: # probably control character, don't use actual
            uname = control_names.get(x, '')
            f.write(u'{0:>6x} {1}    {2}\n'.format(x, cat, uname))
        else:
            f.write(u'{0:>6x} {1}  {2}  {3}\n'.format(x, cat, char, uname))
# may as well describe the types we logged.
for cat, count in counts.items():
    print('{0} chars of category, {1}'.format(count, cat))

이 과정은 약 1 분 정도 걸리며 데이터 파일을 볼 수 있으며 파일 뷰어에서 유니 코드를 표시 할 수 있습니다. 범주에 대한 정보는 여기 에서 찾을 수 있습니다 . 카운트를 기준으로 Cn 및 Co 카테고리를 제외하면 결과가 향상 될 수 있습니다. Cn 및 Co 카테고리는 관련 기호가 없습니다.

$ python uni.py

16 진 맵핑, 카테고리를 표시합니다. , symbol (이름을 얻지 못하면 제어 문자) 및 기호 이름을 표시합니다. 예 :

less유닉스 또는 Cygwin을 권장 합니다 (전체 파일을 출력에 출력하지 마십시오).

$ less unidata

예를 들어 파이썬 2 (유니 코드 5.2)를 사용하여 샘플링 한 다음 줄과 유사하게 표시됩니다.

     0 Cc NUL
    20 Zs     SPACE
    21 Po  !  EXCLAMATION MARK
    b6 So    PILCROW SIGN
    d0 Lu  Ð  LATIN CAPITAL LETTER ETH
   e59 Nd    THAI DIGIT NINE
  2887 So    BRAILLE PATTERN DOTS-1238
  bc13 Lo    HANGUL SYLLABLE MIH
  ffeb Sm    HALFWIDTH RIGHTWARDS ARROW

Anaconda의 Python 3.5에는 유니 코드 8.0이 있으며 대부분 3을 가정합니다.


답변

유니 코드 문자를 파일로 인쇄하는 방법 :

이것을 foo.py 파일에 저장하십시오 :

#!/usr/bin/python -tt
# -*- coding: utf-8 -*-
import codecs
import sys
UTF8Writer = codecs.getwriter('utf8')
sys.stdout = UTF8Writer(sys.stdout)
print(u'e with obfuscation: é')

그것을 실행하고 출력을 파일로 파이프하십시오.

python foo.py > tmp.txt

tmp.txt를 열고 내부를 보면 다음과 같습니다.

el@apollo:~$ cat tmp.txt
e with obfuscation: é

따라서 난독 화 표시가있는 유니 코드 e를 파일에 저장했습니다.


답변

이 오류는 유니 코드가 아닌 문자열을 인코딩하려고 할 때 발생합니다. 일반 ASCII라고 가정하고 디코딩하려고 시도합니다. 두 가지 가능성이 있습니다.

  1. 바이트 문자열로 인코딩하고 있지만 codecs.open을 사용했기 때문에 write 메소드에는 유니 코드 객체가 필요합니다. 그래서 당신은 그것을 인코딩하고 그것을 다시 해독하려고합니다. 시험:f.write(all_html)대신 .
  2. all_html은 실제로 유니 코드 객체가 아닙니다. 당신이 할 때 .encode(...), 먼저 그것을 해독하려고 시도합니다.