弄乱我的unicode输出 - 但是在哪里以及如何?

时间:2016-07-15 16:41:20

标签: python file-io unicode encoding nltk

我正在对一些文本文件进行单词计数,将结果存储在字典中。我的问题是输出到文件后,即使它们在原始文本中,单词也不会正确显示。 (我使用TextWrangler查看它们)。 例如,短划线在原始中显示为短划线,但在输出中显示为 \ u2014 ;在输出中,非常单词也以 u 为前缀。

问题

我不知道我的剧本在何处,何时以及如何发生。

我正在使用codecs.open()阅读该文件,并将其与codecs.open()json.dump()一起输出。他们都以同样的方式出错了。介于两者之间,一切都是

  1. 标记化

  2. 正则表达式

  3. 收集字典

  4. 而且我不知道在哪里搞砸了;我已取消激活令牌化和大多数其他功能无效。所有这些都发生在Python 2中。 根据之前的建议,我尝试用Unicode保留脚本中的所有内容。

    这是我做的(省略了非相关代码):

    #read in file, iterating over a list of "fileno"s
    with codecs.open(os.path.join(dir,unicode(fileno)+".txt"), "r", "utf-8") as inputfili:
                inputtext=inputfili.read()
    
    #process the text: tokenize, lowercase, remove punctuation and conjugation
    content=regular expression to extract text w/out metadata
    contentsplit=nltk.tokenize.word_tokenize(content)
    text=[i.lower() for i in contentsplit if not re.match(r"\d+", i)]
    text= [re.sub(r"('s|s|s's|ed)\b", "", i) for i in text if i not in string.punctuation]
    
    #build the dictionary of word counts
    for word in text:
        dicti[word].append(word)
    
    #collect counts for each word, make dictionary of unique words
    dicti_nos={unicode(k):len(v) for k,v in dicti.items()}
    hapaxdicti= {k:v for k,v in perioddicti_nos.items() if v == 1}
    
    #sort the dictionary
    sorteddict=sorted(dictionary.items(), key=lambda x: x[1], reverse=True)
    
    #output the results as .txt and json-file
    with codecs.open(file_name, "w", "utf-8") as outputi:
        outputi.write("\n".join([unicode(i) for i in sorteddict]))
    with open(file_name+".json", "w") as jsonoutputi:
        json.dump(dictionary, jsonoutputi,  encoding="utf-8")
    

    编辑:解决方案

    看起来我的主要问题是以错误的方式编写文件。如果我将代码更改为下面的代码,那么事情就会成功。看起来加入一个(字符串,数字)元组的列表搞砸了字符串部分;如果我先加入元组,事情就会奏效。

    对于json输出,我必须更改为codecs.open()并将ensure_ascii设置为False。显然只是将encoding设置为utf-8并不像我想的那样做。

    with codecs.open(file_name, "w", "utf-8") as outputi:
        outputi.write("\n".join([":".join([i[0],unicode(i[1])]) for i in sorteddict]))
    
    with codecs.open(file_name+".json", "w", "utf-8") as jsonoutputi:
        json.dump(dictionary, jsonoutputi,  ensure_ascii=False)
    

    感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

由于您的示例是部分伪代码,因此无法运行真正的测试并为您提供运行且已经过测试的内容,但是从阅读您提供的内容开始我认为您可能会误解Unicode在Python中的工作方式2。

unicode类型(例如通过unicode()unichr()函数生成)意味着是Unicode字符串的内部表示,可用于字符串操作和比较目的。它没有相关的编码。 unicode()函数将缓冲区作为其第一个参数,将编码作为其第二个参数,并使用该编码解释该缓冲区,以生成内部可用的Unicode字符串,该字符串从该点开始不受编码的影响。

那个Unicode字符串不是要写出来的;所有文件格式都假设有一些编码,并且在将Unicode字符串写入文件之前,您应该再次提供一个。你有unicode(fileno)unicode(k)unicode(i)这样的结构的每个地方都是可疑的,因为你依赖于默认编码(这可能不是你想要的)和因为您正在将大部分这些值直接暴露给文件系统。

使用这些Unicode字符串后,可以使用内置方法encode()将所需的编码作为参数,将它们打包成普通字节的字符串,按照您的要求设置编码

回顾上面的示例,您的inputtext变量是一个包含按UTF-8编码编码的数据的普通字符串。这不是Unicode。您可以使用类似inputuni = unicode(inputtext, 'utf-8')的操作将其转换为Unicode字符串,如果您愿意,可以对其进行操作,但对于您正在做的事情,您甚至可能认为没有必要。如果您确实将其转换为Unicode,但您必须在您计划写入文件的任何Unicode字符串上执行等效的inputuni.encode('UTF-8')