Python删除无效的ascii字符

时间:2016-12-07 10:43:11

标签: python unicode ascii

我最近写了一个脚本来从pdf中提取所有书签并将它们保存在docx文件中。它适用于90%的文件,但不幸的是有一些似乎与unicode有问题。

我在这样的列表中得到了书签:

[[u'3. Mechatronik f\xfcr Doppelkupplungsgetriebe, Sicherungshalter B, Sicherung 14 auf Sicherungshalter C', 2],
[u'4. Geber f\xfcr Getriebeeingangsdrehzahl, Hydraulikdruckgeber 1 f\xfcr automatisches Getriebe, Magnetventil 2, Magnetventil \x04, Magnetventil 5', 2],
[u'5. W\xe4hlhebel, Schalter f\xfcr W\xe4hlhebel in P gesperrt, Magnet f\xfcr W\xe4hlhebelsperre', 2], 
[u'6. W\xe4hlhebel, Geber 2 f\xfcr Antriebswellendrehzahl, W\xe4hlhebel-Positionsanzeige', 2]]

当我尝试运行该功能时,我收到错误:

ValueError('All strings must be XML compatible: Unicode or ASCII, no NULL bytes or control characters',)

代码:

from docx import Document

list1 = [[u'3. Mechatronik f\xfcr Doppelkupplungsgetriebe, Sicherungshalter B, Sicherung 14 auf Sicherungshalter C', 2],
    [u'4. Geber f\xfcr Getriebeeingangsdrehzahl, Hydraulikdruckgeber 1 f\xfcr automatisches Getriebe, Magnetventil 2, Magnetventil \x04, Magnetventil 5', 2],
    [u'5. W\xe4hlhebel, Schalter f\xfcr W\xe4hlhebel in P gesperrt, Magnet f\xfcr W\xe4hlhebelsperre', 2],
    [u'6. W\xe4hlhebel, Geber 2 f\xfcr Antriebswellendrehzahl, W\xe4hlhebel-Positionsanzeige', 2]]

def save_docx(list1):
document = Document('default.docx')
file = open("Error_Log.txt", 'w')
for i in list1:
    try:
        p = document.add_paragraph()
        p.add_run(i[0]).bold = True
    except Exception as e:
        file.write(repr(e) + '\n')
file.close()
document.save('Bookmarks.docx')

save_docx(list1)

我猜这个问题是\x0,但我无法弄清楚如何在不破坏整个文件的情况下删除这样的部分。 我尝试了不同的编码以及我在网上找到的任何其他内容但到目前为止没有任何工作。

非常感谢任何帮助!

1 个答案:

答案 0 :(得分:1)

您的假设似乎是正确的:\x04是一个控制字符,您的错误消息明确指出不允许控件。

您可以在将字符串中的控制字符添加到文档之前对其进行过滤,这样可以解决您的问题。这可以使用Python的unicodedata module,特别是unicodedata.category来完成。您要排除的类别以“C”(来自http://www.unicode.org/reports/tr44/#GC_Values_Table)开头,其中包含所有控制字符。

以下内容应该有效,取代您当前的add_run行:

line = filter(lambda c: unicodedata.category(c)[0] != 'C', i[0])
p.add_run(line).bold = True

顺便说一下,在unicode字符串中包含unicode字符的典型方法是使用\ uXXXX,而不是\ xXX(其中XXXX是unicode代码点的十六进制)。