Pythonでファイルから文字を読み取る


102

テキストファイルには、「これは好きではありません」という文字列があります。

しかし、それを文字列に読み込むと、「こんな風に\ xe2 \ x80 \ x98t」のようになります。\ u2018が「 '」のUnicode表現であることを理解しています。私が使う

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

読み取りを行うコマンド。

さて、文字列に読み込まれたときに、「I like \ xe2 \ x80 \ x98t like this like this」の代わりに、「I do n't like this」のように文字列を読み取ることはできますか?

2番目の編集:この問題を解決するためにマッピングを使用する人を見たことがありますが、実際には、この種のANSIをUnicodeに(またはその逆に)変換する組み込みの変換はありませんか?


一部のコメント:この問題を解決するためにマッピングを使用している人を見たことがありますが、実際には、この種のANSIをUnicodeに(またはその逆に)変換する組み込みの変換はありませんか?ありがとう!
Graviton

何十万ものUnicodeコードポイントがあるため、ありません。どの文字をどのASCII文字にマッピングするかをどのように決定しますか?
ジョンミリキン、

2
ところで、テキストファイルが壊れています!U + 2018は「LEFT SINGLE QUOTATION MARK」であり、アポストロフィではありません(U + 0027が最も一般的です)。

ジョン、あなたのコメントは少なくとも一般的な意味で間違っています。iconv libは、Unicode文字をASCIIに音訳するために使用できます(ロケールに依存します。$ python -c 'print u "\ u2018" .encode( "utf-8")' | iconv -t 'ascii // translit' | xxd 0000000:270a

つまり、UNICODEをASCIIに変換する必要があります(その逆ではありません)。
2008

回答:


157

参照:http : //docs.python.org/howto/unicode

したがって、ファイルからの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で文字列にファイルを適切に読み取ることができることであると想定しています。UnicodeからASCII文字列に変換しようとしている場合、Unicode文字は必ずしもASCIIで存在する必要はないため、直接変換する方法はありません。

ASCII文字列に変換しようとしている場合は、次のいずれかを試してください。

  1. この特定の例のようないくつかの特殊なケースのみを処理する場合は、特定のUnicode文字を同等のASCII文字に置き換えます。

  2. 使用unicodedataモジュールのnormalize()string.encode()同等の次に近いASCII(refにあなたができる最善のように変換するために、方法を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 2015年

15

考慮すべき点がいくつかあります。

\ u2018文字は、PythonでのUnicode文字列の表現のフラグメントとしてのみ表示される場合があります。たとえば、次のように記述した場合:

>>> 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でUnicode序数をUnicode序数にマッピングする場合({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を使用すると、Unicode文字を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

どういうわけか、Unicodeエスケープ文字を含む非Unicode文字列がある可能性があります。例:

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

これは実際に前に一度起こった。unicode_escapeコーデックを使用して文字列をデコードし、Unicodeにしてから、任意の形式にエンコードできます。

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

1

これは、Unicodeでエンコードされた文字列を表示するPythonの方法です。しかし、文字列を画面に印刷したり、問題なく新しいファイルに書き込んだりできるはずです。

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

1

実際、U + 2018は特殊文字 'のUnicode表現です。必要に応じて、次のコードでそのキャラクターのインスタンスを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

あなたが見ている「私はこのような\ xe2 \ x80 \ x98t」はPythonがstrと呼ぶものです。Pythonのユニコードインスタンスであるu'I don \ u2018t like this 'のutf-8エンコーディングのようです。前者では.decode( 'utf-8')を、後者では.encode( 'utf-8')を呼び出してみてください。
ローガン

@hop:おっと、ford ord()は16進数ではなく10進数を返します。キャッチありがとうございます。
ジョンミリキン、
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.