【问题标题】:read CSV file and validate column which on the basis of UTF-8 character读取 CSV 文件并验证基于 UTF-8 字符的列
【发布时间】:2017-02-09 14:12:59
【问题描述】:

我必须读取一个包含列(PersonName、age、address)的 CSV 文件,并且我必须验证 PersonName。 "PersonName 只能包含 UTF-8 字符。"

我使用的是python3.x,所以打开文件后无法使用解码方法。

请告诉我如何打开和读取文件,以便忽略不包含任何 UTF-8 字符的 PersonName,我可以转到下一行进行验证。

【问题讨论】:

  • 为什么不能使用decode
  • 那么其余字段的编码是什么? ASCII?还有什么?通常,整个 文件 具有单一编码,违反该单一编码意味着数据已损坏,您无法真正信任它。请记住,仅包含 ASCII 字符的字段也是合法的 UTF-8(UTF-8 是 ASCII 超集)。
  • 我不关心其他领域。我有一个 CSV 文件,我只想验证 PersonName 应该只包含 UTF-8 字符。
  • @AChampion 当我们打开文件时,python3.x 返回 unicode。所以我不能对未编码的数据使用解码方法。在 Python3.x 中 string.decode() 不起作用
  • @ShadowRanger 感谢您的回复。好吧,我同意通常整个文件都有一个编码。但我只想验证 PersonName 是否只有 UTF-8 字符。

标签: python python-3.x csv unicode utf-8


【解决方案1】:

假设文件的其余部分不需要检查或者是 UTF-8 合法的(包括 ASCII 数据),您可以使用 encoding='utf-8'errors='replace' open 文件。这会将任何无效字节(UTF-8 编码)更改为 Unicode 替换字符 \ufffd。或者,为了保留数据,您可以使用'surrogateescape' 作为errors 处理程序,它使用专用Unicode 代码以一种以后可以撤消的方式表示原始值。然后,您可以随时检查:

with open(csvname, encoding='utf-8', errors='replace', newline='') as f:
    for PersonName, age, address in csv.reader(f):
        if '\ufffd' in PersonName:
            continue
        ... PersonName was decoded without errors, so process the row ...

或者使用surrogateescape,您可以确保在写入时恢复其他字段中的任何非UTF-8 数据(如果“可能”):

with open(incsvname, encoding='utf-8', errors='surrogateescape', newline='') as inf,\
     open(outcsvname, 'w', encoding='utf-8', errors='surrogateescape', newline='') as outf:
    csvout = csv.writer(outf)
    for PersonName, age, address in csv.reader(f):
        try:
            # Check for surrogate escapes, and reject PersonNames containing them
            # Most efficient way to do so is a test encode; surrogates will fail
            # to encode with default error handler
            PersonName.encode('utf-8')
        except UnicodeEncodeError:
            continue  # Had non-UTF-8, skip this row

        ... PersonName was decoded without surrogate escapes, so process the row ...

        # You can recover the original file bytes in your code for a field with:
        #     fieldname.encode('utf-8', errors='surrogateescape')
        # Or if you're just passing data to a new file, write the same strings
        # back to a file opened with the same encoding/errors handling; the surrogates
        # will be restored to their original values:
        csvout.writerow([PersonName, age, address])

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-20
    • 1970-01-01
    • 2017-06-28
    • 1970-01-01
    • 2016-07-25
    • 1970-01-01
    相关资源
    最近更新 更多