使用 python 识别垃圾 unicode 字符串

Identify garbage unicode string using python

我的脚本是从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(),它将识别垃圾字符串并只处理有效字符串。

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

value.decode('utf8')

The expected output are string with Chinese and English string to be process

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

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

在这种情况下,您的文本是使用 Windows 1252 codepage; the U+20AC EURO SIGN in the text is typical of CP1252 Mojibakes. The original encoding could be one of the GB* family of Chinese encodings 或多次往返 UTF-8 - CP1252 Mojibake 解码的。我不能确定哪一个,我看不懂中文,我也没有你的完整数据; CP1252 Mojibakes 包含不可打印的字符,如 0x81 和 0x8D 字节,当您在此处发布问题时,这些字符可能会丢失。

我会安装 ftfy project; it won't fix GB* encodings (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 在序列怪异 量表上得分很高。您可以尝试为您的数据找到一个合适的阈值,在该阈值之前您称数据最有可能被损坏。

不过,我认为我们可以使用非零 return 值作为另一个测试的起点。英文文本应在该等级上得分为 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

(这里是 ftfy 开发人员)

我猜到文字很可能是'袋袋与朋友们电子商'。我不得不猜测“友”、“子”和“商”这些字符,因为一些不可打印的字符是您问题中的字符串中缺少的字符。猜的时候,我从少量的可能性中挑选了最常见的字符。我不知道 "dcx" 去了哪里,也不知道它为什么在那里。

Google 翻译在这里不是很有用,但它似乎与电子商务有关。

所以这就是您的文本发生的所有事情:

  1. 它被编码为 UTF-8 并被错误地解码为草率-windows-1252,两次
  2. 它在 UTF-8 序列的中间插入了字母 "dcx"
  3. windows-1252 中不存在的字符 -- 字节值为 81、8d、8f、90 和 9d -- 已被删除
  4. 一个不间断的space(字节值a0)被从末尾移除

如果只发生第一个问题,ftfy.fix_text_encoding 就能解决它。剩余的问题可能只是在您尝试将字符串放到 Stack Overflow 上时发生的。

所以这是我的建议:

  • 找出谁总是将数据错误地解码为马虎-windows-1252,并让他们将其解码为 UTF-8。
  • 如果您再次遇到这样的字符串,请尝试 ftfy.fix_text_encoding