使用python识别垃圾unicode字符串

时间:2015-03-16 07:58:04

标签: python python-2.7 python-unicode mojibake

我的脚本是从csv文件读取数据,csv文件可以有多个英文或非英文单词串。

有时候文本文件有垃圾字符串,我想识别那些字符串并跳过这些字符串并处理其他字符串

doc = codecs.open(input_text_file, "rb",'utf_8_sig')
fob = csv.DictReader(doc)
for row, entry in enumerate(f):
    if is_valid_unicode_str(row['Name']):
         process_futher

def is_valid_unicode_str(value):
     try:
         function
         return True
     except UnicodeEncodeError:
         return false

csv输入:

"Name"
"袋è¢âdcx€¹Ã¤Â¸Å½Ã¦Å“‹å‹们çâ€ÂµÃ¥Â­Âå•â€"
"元大寶來證券"
"John Dove"

我想玷污函数is_valid_unicode_str(),它将识别垃圾字符串并仅处理有效字符串。

我尝试使用解码但是在解码垃圾字符串时它没有失败

value.decode('utf8')
  

预期输出为字符串,中文和英文字符串为进程

请您指导我如何实现过滤有效Unicode文件的功能?

2 个答案:

答案 0 :(得分:5)

(ftfy开发人员)

我发现文字很可能是'袋袋与朋友们电子商'。我不得不猜测人物友,子和商,因为一些不可打印的字符是你问题中字符串中缺少的字符。在猜测时,我从少数几种可能性中选择了最常见的角色。我不知道“dcx”在哪里或为什么会在那里。

谷歌翻译在这里不是很有帮助,但它似乎意味着电子商务。

所以这是你的文字发生的一切:

  1. 它被编码为UTF-8并被错误解码为sloppy-windows-1252,两次
  2. 在UTF-8序列的中间插入了字母“dcx”
  3. Windows-1252中不存在的字符 - 字节值为81,8d,8f,90和9d - 已被删除
  4. 从末尾删除了不间断的空格(字节值a0)
  5. 如果刚出现第一个问题,ftfy.fix_text_encoding就可以修复它。当你试图将字符串放到Stack Overflow上时,剩下的问题可能就发生了。

    所以这是我的建议:

    • 找出谁不断将数据解码为sloppy-windows-1252,并让他们将其解码为UTF-8。
    • 如果您最终再次使用此类字符串,请尝试使用ftfy.fix_text_encoding

答案 1 :(得分:2)

你有Mojibake strings;文本编码为一个(正确的)编解码器,然后解码为另一个。

在这种情况下,您的文字已使用Windows 1252 codepage解码;文本中的U+20AC EURO SIGN是典型的CP1252 Mojibakes。原始编码可以是GB* family of Chinese encodings之一,也可以是多次往返UTF-8 - CP1252 Mojibake。哪一个我无法确定,我看不懂中文,也没有你的全部数据; CP1252 Mojibakes包含不可打印的字符,如0x81和0x8D字节,当您在此处发布问题时可能会丢失。

我安装ftfy project;它不会修复GB *编码(I requested the project add support),但它包含一个名为sloppy-windows-1252的新编解码器,它可以让你用该编解码器反转错误的解码:

>>> import ftfy  # registers extra codecs on import
>>> text = u'袋è¢âdcx€¹Ã¤Â¸Å½Ã¦Å“‹å‹们çâ€ÂµÃ¥Â­Âå•â€'
>>> print text.encode('sloppy-windows-1252').decode('gb2312', 'replace')
猫垄�姑�⑩dcx�盲赂沤忙��姑ヂ�姑ぢ宦�р�得ヂ�氓�⑩�
>>> print text.encode('sloppy-windows-1252').decode('gbk', 'replace')
猫垄鈥姑�⑩dcx�盲赂沤忙艙鈥姑ヂ鈥姑ぢ宦�р�得ヂ�氓鈥⑩�
>>> print text.encode('sloppy-windows-1252').decode('gb18030', 'replace')
猫垄鈥姑⑩dcx�盲赂沤忙艙鈥姑ヂ鈥姑ぢ宦р�得ヂ氓鈥⑩�
>>> print text.encode('sloppy-windows-1252').decode('utf8', 'ignore').encode('sloppy-windows-1252').decode('utf8', 'replace')
袋�dcx与朋�们���

U+FFFD REPLACEMENT CHARACTER显示解码并不完全成功,但这可能是由于您复制的字符串缺少任何不可打印或使用0x81或0x8D字节的事实。

您可以尝试以这种方式修复数据;从文件数据开始,尝试在编码为sloppy-windows-1252后解码为GB *编解码器之一,或者从UTF-8往返两次,看看哪种最适合。

如果这还不够(您无法修复数据),可以使用ftfy.badness.sequence_weirdness() function尝试检测问题:

>>> from ftfy.badness import sequence_weirdness
>>> sequence_weirdness(text)
9
>>> sequence_weirdness(u'元大寶來證券')
0
>>> sequence_weirdness(u'John Dove')
0

Mojibakes在序列怪异比例上得分很高。您可以尝试为您的数据找到合适的阈值,以便您调用最有可能损坏的数据。

但是,我认为我们可以使用非零返回值作为另一个测试的起点。英文文本应该按该等级评分为0,中文文本也应如此。中文与英语混合仍然可以得分超过0,但是当你可以使用破碎文本时,你无法将中文文本编码为CP-1252编解码器:

from ftfy.badness import sequence_weirdness

def is_valid_unicode_str(text):
    if not sequence_weirdness(text):
        # nothing weird, should be okay
        return True
    try:
        text.encode('sloppy-windows-1252')
    except UnicodeEncodeError:
        # Not CP-1252 encodable, probably fine
        return True
    else:
        # Encodable as CP-1252, Mojibake alert level high
        return False