【问题标题】:To clean text belonging to different languages in Python在 Python 中清理属于不同语言的文本
【发布时间】:2016-05-23 07:23:08
【问题描述】:

我有一个文本集合,其中包含完全用英语、印地语或马拉地语的句子,每个句子的 id 分别为 0、1、2,分别代表文本的语言。

无论任何语言的文本都可能带有 HTML 标记、标点符号等。

我可以使用下面的代码清理英文句子:

import HTMLParser
import re
from nltk.corpus import stopwords
from collections import Counter
import pickle
from string import punctuation

#creating html_parser object 
html_parser = HTMLParser.HTMLParser()
cachedStopWords = set(stopwords.words("english"))

def cleanText(text,lang_id): 

    if lang_id == 0:
        str1 = ''.join(text).decode('iso-8859-1')


    else:
        str1 = ''.join(text).encode('utf-8')

    str1 = html_parser.unescape(str1)    
    cleanr = re.compile('<.*?>')
    cleantext = re.sub(cleanr, '', str1)
    #print "cleantext before puncts removed : " + cleantext
    clean_puncts = re.compile(r'[\s{}]+'.format(re.escape(punctuation)))
    cleantext = re.sub(clean_puncts,' ',cleantext)
    #print " cleantext after puncts removed : " + cleantext
    cleanest = cleantext.lower()
    if lang_id == 0:
        cleanertext = ' '.join([word for word in cleanest.split() if word not in cachedStopWords])       
        words = re.findall(r"[\w']+", cleanertext)
        words_final = [x.encode('UTF8') for x in words]
    else:
        words_final = cleanest.split()
    return words_final

但它给了我以下印地语和马拉地语文本的错误:

UnicodeDecodeError: 'ascii' codec can't decode byte 0xeb in position 104: ordinal not in range(128)

此外,它会删除所有单词。

印地语文本就像

&lt;p&gt;भारत का इतिहास काफी समृद्ध एवं विस्तृत है। &lt;/p&gt;

我怎样才能对印地语或马拉地语文本做同样的事情?

【问题讨论】:

  • 你能把文字贴在网上吗?
  • 不同line and parts of line。在编码之前准备语言字符串。拳头unicode 稍后str
  • python2python3?
  • @alvas : python 2.7
  • 你能显示完整的代码吗?答案很大程度上取决于您阅读文件的方式。

标签: python python-2.7 unicode nltk


【解决方案1】:

如果没有完整的文本文件,我们能提供的解决方案也只能是摸不着头脑。

首先,检查你读入cleanText()的字符串的类型,它真的是一个unicode还是一个字节字符串?见byte string vs. unicode string. Python

因此,如果您已正确读取文件并确保所有内容都是 unicode,那么您如何管理字符串(在 python2 或 3 中)应该没有问题。下面的例子证实了这一点:

>>> from HTMLParser import HTMLParser
>>> hp = HTMLParser()
>>> text = u"&lt;p&gt;भारत का इतिहास काफी समृद्ध एवं विस्तृत है। &lt;/p&gt;"
>>> hp.unescape(text)
u'<p>\u092d\u093e\u0930\u0924 \u0915\u093e \u0907\u0924\u093f\u0939\u093e\u0938 \u0915\u093e\u092b\u0940 \u0938\u092e\u0943\u0926\u094d\u0927 \u090f\u0935\u0902 \u0935\u093f\u0938\u094d\u0924\u0943\u0924 \u0939\u0948\u0964 </p>'
>>> print hp.unescape(text)
<p>भारत का इतिहास काफी समृद्ध एवं विस्तृत है। </p>
>>> hp.unescape(text).split()
[u'<p>\u092d\u093e\u0930\u0924', u'\u0915\u093e', u'\u0907\u0924\u093f\u0939\u093e\u0938', u'\u0915\u093e\u092b\u0940', u'\u0938\u092e\u0943\u0926\u094d\u0927', u'\u090f\u0935\u0902', u'\u0935\u093f\u0938\u094d\u0924\u0943\u0924', u'\u0939\u0948\u0964', u'</p>']
>>> print " ".join(hp.unescape(text).split())
<p>भारत का इतिहास काफी समृद्ध एवं विस्तृत है। </p>

即使使用正则表达式操作,也没有问题:

>>> import re
>>> from string import punctuation
>>> p = re.compile(r'[\s{}]+'.format(re.escape(punctuation)))
>>> new_text = " ".join(hp.unescape(text).split())
>>> re.sub(p,' ', new_text)
u' p \u092d\u093e\u0930\u0924 \u0915\u093e \u0907\u0924\u093f\u0939\u093e\u0938 \u0915\u093e\u092b\u0940 \u0938\u092e\u0943\u0926\u094d\u0927 \u090f\u0935\u0902 \u0935\u093f\u0938\u094d\u0924\u0943\u0924 \u0939\u0948\u0964 p '
>>> print re.sub(p,' ', new_text)
 p भारत का इतिहास काफी समृद्ध एवं विस्तृत है। p 

查看"How to stop the pain" 并遵循本次演讲中的最佳实践很可能会解决您的 unicode 问题。在http://nedbatchelder.com/text/unipain.html 上滑动。

也要看看这个:PyCon14 上的https://www.youtube.com/watch?v=Mx70n1dL534(但仅适用于python2.x

像这样打开一个 utf8 文件也可以解决您的问题:

import io
with io.open('myfile.txt', 'r', encoding='utf8') as fin:
    for line in fin:
        clean_text(line)

如果 STDIN 和 STDOUT 给您带来问题,请参阅 https://daveagp.wordpress.com/2010/10/26/what-a-character/

另见:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-20
    • 1970-01-01
    • 2019-06-28
    • 1970-01-01
    • 1970-01-01
    • 2014-09-30
    相关资源
    最近更新 更多