如何解码中文文本中的unicode

时间:2015-10-23 03:03:46

标签: python unicode

with open('result.txt', 'r') as f:
data = f.read()

print 'What type is my data:'
print type(data)

for i in data:
    print "what is i:"
    print i
    print "what type is i"
    print type(i)


    print i.encode('utf-8')

我有字符串文件,我正在尝试读取文件并拆分 按空格划分的单词并将其保存到列表中。以下是我的代码:

以下是我的错误消息: enter image description here

有人请帮忙!

更新

我将在这里详细描述我要做的事情,以便为人们提供更多背景信息:我想要做的目标是: 1.取一个中文文本并将其分解为句子,并检测基本的结尾标点符号。 2.取每个句子并使用工具jieba将字符标记为有意义的单词。例如,两个汉字学,生,将组合在一起产生一个标记'学生'(意思是学生)。 3.将句子中的所有标记保存到列表中。所以最终的列表里面会有多个列表,因为段落中有多个句子。

# coding: utf-8 
#encoding=utf-8

import jieba

cutlist = "。!?".decode('utf-8')
test = "【明報專訊】「吉野家」and Peter from US因被誤傳採用日本福島米而要報警澄清,並自爆用內地黑龍江米,日本料理食材來源惹關注。本報以顧客身分向6間日式食店查詢白米產地,其中出售逾200元日式豬扒飯套餐的「勝博殿日式炸豬排」也選用中國大連米,誤以為該店用日本米的食客稱「要諗吓會否再幫襯」,亦有食客稱「好食就得」;壽司店「板長」店員稱採用香港米,公關其後澄清來源地是澳洲,即與平價壽司店「爭鮮」一樣。有飲食界人士稱,雖然日本米較貴、品質較佳,但內地米品質亦有保證。"

#FindToken check whether the character has the ending punctuation
def FindToken(cutlist, char):
    if char in cutlist:
        return True
    else:
        return False

'''
剪切检查字符串列表中的每个项目,如果该项目不是结束标点符号,则将其保存到名为line的临时列表中。当遇到结束标点符号时,它会将已在列表行中收集的完整句子保存到最终列表中。 '''

def cut(cutlist,test):
    l = []
    line = []
    final = []

'''
检查字符串列表中的每个项目,如果该项目不是结束标记,它 将它保存到名为line的临时列表中。当遇到结束冲击时,它会将已在列表行中收集的完整句子保存到最终列表中。 '''

    for i in test:
        if i == ' ':
            line.append(i)

        elif FindToken(cutlist,i):
            line.append(i)
            l.append(''.join(line))
            line = []
        else:
            line.append(i)

    temp = [] 
    #This part iterate each complete sentence and then group characters according to its context.
    for i in l:
        #This is the function that break down a sentence of characters and group them into phrases
        process = list(jieba.cut(i, cut_all=False))

        #This is puting all the tokenized character phrases of a sentence into a list. Each sentence 
        #belong to one list.
        for j in process:
            temp.append(j.encode('utf-8')) 
            #temp.append(j) 
        print temp 

        final.append(temp)
        temp = [] 
    return final 


cut(list(cutlist),list(test.decode('utf-8')))

这是我的问题,当我输出我的最终列表时,它给出了以下结果的列表:

[u'\u3010', u'\u660e\u5831', u'\u5c08\u8a0a', u'\u3011', u'\u300c', u'\u5409\u91ce\u5bb6', u'\u300d', u'and', u' ', u'Peter', u' ', u'from', u' ', u'US', u'\u56e0', u'\u88ab', u'\u8aa4\u50b3', u'\u63a1\u7528', u'\u65e5\u672c', u'\u798f\u5cf6', u'\u7c73', u'\u800c', u'\u8981', u'\u5831\u8b66', u'\u6f84\u6e05', u'\uff0c', u'\u4e26', u'\u81ea\u7206', u'\u7528\u5167', u'\u5730', u'\u9ed1\u9f8d', u'\u6c5f\u7c73', u'\uff0c', u'\u65e5\u672c\u6599\u7406', u'\u98df\u6750', u'\u4f86\u6e90', u'\u60f9', u'\u95dc\u6ce8', u'\u3002']

如何将unicode列表转换为普通字符串?

4 个答案:

答案 0 :(得分:6)

让我给你一些提示:

  • 在尝试迭代单词之前,您需要将从UTF-8读取的字节解码为Unicode
  • 当您阅读文件时,您将无法获得Unicode。你只是获得普通的字节。 (我想你知道,因为你已经在使用decode()。)
  • 有一个标准功能可以按空格分开"叫split()
  • 当你说for i in data时,你说你想要迭代你刚读过的文件的每个字节。循环的每次迭代都是单个字符。我不确定这是否是您想要的,因为这意味着您必须手动进行UTF-8解码(而不是使用decode(),而open('file.txt').read().decode('utf-8').split() 必须在整个UTF-8字符串。)。

换句话说,这里有一行代码:

>>> data = u"わかりません"
>>> data
u'\u308f\u304b\u308a\u307e\u305b\u3093'
>>> data_you_would_see_in_a_file = data.encode('utf-8')
>>> data_you_would_see_in_a_file
'\xe3\x82\x8f\xe3\x81\x8b\xe3\x82\x8a\xe3\x81\xbe\xe3\x81\x9b\xe3\x82\x93'
>>> for each_unicode_character in data_you_would_see_in_a_file.decode('utf-8'):
...     print each_unicode_character
... 
わ
か
り
ま
せ
ん

如果这是作业,请不要把它转过来。你的老师会在你身上。 ; - )

编辑:以下是如何在python中对unicode字符进行编码和解码的示例:

u""

首先要注意的是Python(嗯,至少Python 2)在字符串常量上使用u表示法(注意b""前缀)来表明它们是Unicode。在Python 3中,默认情况下字符串是Unicode,但如果需要字节字符串,则可以使用.encode()

如您所见,Unicode字符串由双字节字符组成。当你读取文件时,你得到一个单字节字符串(这相当于你调用.decode()时得到的字符串。所以如果你有文件中的字节,你必须调用' '来将它们转换回Unicode。然后你可以迭代每个字符。

分裂"按空间"是每种语言都有的独特之处,因为许多语言(例如,中文和日语)不像大多数欧洲语言那样使用People字符。我不知道如何在Python中做到这一点,但我确信有办法。

答案 1 :(得分:3)

当您使用大多数(所有?)编解码器encode上调用strencode真的没有意义; str是面向字节的类型,而不是像unicode这样需要编码的真实文本类型,Python is implicitly decodeing it as ASCII first,然后使用指定的编码进行编码。如果您希望将str解释为ASCII以外的其他内容,则需要decode从类似字节的str到真实文本unicode

i.encode('utf-8')istr,您隐含地说i是逻辑文本(由区域设置默认编码中的字节表示) ,而不是二进制数据。所以为了encode它,它首先需要解码它以确定"逻辑"文字是。您的输入可能以某些ASCII超集(例如latin-1,甚至utf-8)编码,并包含非ASCII字节;它尝试decode使用ascii编解码器(以找出它需要编码为utf-8的真正的Unicode序数),然后失败。

您需要执行以下操作之一:

  1. 明确decode您使用正确的编解码器读取的str(获取unicode个对象),然后encode返回utf-8
  2. 让Python隐含地为你做#1的工作。而不是使用openimport io和使用io.open(仅限Python 2.7+;在Python 3 +上,io.openopen是相同的功能),得到一个像Python 3 open一样的open。您可以传递此openencoding参数(例如io.open('/path/to/file', 'r', encoding='latin-1'))和read从生成的文件对象中获取decode - ed {{1对象(然后可以unicode - 编辑你想要的任何东西)。
  3. 注意:如果实际编码类似于encode,则#1将无法工作,并且您将工作推迟到逐个字符迭代之后。对于非ASCII字符,utf-8是多字节的,因此如果您只有一个字节,则不能utf-8(因为计算单个序数需要以下字节)。这是首选使用decode原文为io.open的原因,因此您不必担心此类内容。

答案 2 :(得分:2)

data是Python 2上的字节串(str类型)。你的循环一次查看一个字节(非ascii字符可以用utf-8中的多个字节表示)。

不要在字节上调用.encode()

$ python2
>>> '\xe3'.enϲodе('utf˗8') #XXX don't do it
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe3 in position 0: ordinal not in range(128)
  

我正在尝试读取文件并按空格分割单词并将其保存到列表中。

要使用Unicode文本,请在Python 2中使用unicode类型。您可以使用io.open()从文件中读取Unicode文本(这里是将所有以空格分隔的单词收集到列表中的代码) :

#!/usr/bin/env python
import io

with io.open('result.txt', encoding='utf-8') as file:
    words = [word for line in file for word in line.split()]
print "\n".join(words)

答案 3 :(得分:2)

编码:

$ python
Python 3.7.4 (default, Aug 13 2019, 15:17:50)
[Clang 4.0.1 (tags/RELEASE_401/final)] :: Anaconda, Inc. on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import base64
>>> base64.b64encode("我们尊重原创。".encode('utf-8'))
b'5oiR5Lus5bCK6YeN5Y6f5Yib44CC'

解码:

>>> import base64
>>> str='5oiR5Lus5bCK6YeN5Y6f5Yib44CC'
>>> base64.b64decode(str)
b'\xe6\x88\x91\xe4\xbb\xac\xe5\xb0\x8a\xe9\x87\x8d\xe5\x8e\x9f\xe5\x88\x9b\xe3\x80\x82'
>>> base64.b64decode(str).decode('utf-8')
'我们尊重原创。'
>>>