如何在python中检测未解码的字符?

时间:2015-09-03 17:24:16

标签: python string csv encoding python-2.x

我从csv文件中获取数据,使用它执行某些操作,然后将其写入文本模板。

当我遇到无法编码的字符时会出现问题。

例如,当我使用中文编写的值时,当我使用某种csv编辑器(例如LibreOffice Calc for Linux)打开它时,所选字段为空白。

但是当我在脚本中通过csv.reader获取数据时,我发现它实际上是一个未正确解码的字符串。 当我尝试将其写入模板时,我会得到这个奇怪的 SUB 字符串。

以下是问题的细分:

for row in csv.DictReader(csvfile):
    # take value from the row and store it in a dictionary
    ....
    # take the values from the dictionary and write them to a template
    with open('template.txt', 'r+') as template:
        src = Template(template.read())
        content = src.substitute(rec)

    with open('myoutput.txt', 'w') as bill:
        bill.write(content)

template.txt看起来像这样:

$name
$address
$city
...

所有这些都会生成如下所示的txt文件:

Bill
North Grove 14
Scottsdale
...

如果任何字典值为空,例如一个空字符串'',我的模板呈现函数忽略了标记,例如,如果特定行中缺少address属性,则输出将为

Bill
Scottsdale
...

当我尝试使用我的中文数据时,我的函数会写入数据,因为有问题的字符串不为空。当我将它们写入模板时,最终结果如下所示:

    SUB
    SUB
    Hong Kong
    ...

如何正确显示数据?还有一种方法可以跳过这些数据,例如可以尝试解码数据的东西,如果它不成功,则将其转换为空字符串。 附: try except在此不起作用,因为mystring.encode('utf-8')mystring.encode('latin-1')会对字符串进行编码,但仍然会将其作为垃圾输出。

修改

打印出问题行后,有问题值的输出如下:

{'Name': '\x1a \x1a\x1a', 'State': '\x1a\x1a\x1a'}

2 个答案:

答案 0 :(得分:1)

\x1aASCII substitute character。这就是您在输出中看到“SUB”的原因。此字符通常用作尝试解码字节但失败的程序的替代。

您的CSV文件不包含有效数据。可能它是从包含有效数据的源开始生成的,但文件本身不再包含有效数据。

猜猜:也许,你是用LibreOffice打开文件然后保存的吗?

如果要检查字符串是否包含ASCII不可打印字符,请使用:

def is_printable(data):
    return all(c in string.printable for c in data)

如果要删除ASCII不可打印的字符:

def strip_unprintable(data):
    return ''.join(c for c in data if c in string.printable)

如果要处理Unicode字符串,请将c in string.printable替换为:

ord(c) > 0x1f and ord(c) != 0x7f and not (0x80 <= ord(c) <= 0x9f)

(信用转到What is the range of Unicode Printable Characters?

答案 1 :(得分:0)

感谢@Andrea Corbellini,您的回答帮助我找到了解决方案。

def stringcheck(line):
    for letter in line:
        if letter not in string.printable:
            return 0
    return 1

但是,我不认为这是这种方式最蟒蛇的方式,所以任何有关如何做到这一点的建议都会非常感激。

相关问题