如何使用Python 3查找/替换不可打印/非ascii字符?

问题描述 投票:2回答:3

我有一个文件,.csv文件中的一些行正在干扰数据库导入,因为行中某些字段中的时髦字符。

我搜索过,找到了有关如何在Python 3中替换非ascii字符的文章,但没有任何作用。

当我在vi中打开文件并执行:set list时,在一行的末尾有一个不应该有的$,并且^ I ^ I在下一行的开头。两条线应该是一条连线而不是那里的^。我知道$是'\ n'行的末尾并试图替换它们,但没有任何作用。

我不知道^我代表什么,可能是一个标签。


我试过这个功能无济于事:

def remove_non_ascii(text):
    new_text = re.sub(r"[\n\t\r]", "", text)
    new_text = ''.join(new_text.split("\n"))
    new_text = ''.join([i if ord(i) < 128 else ' ' for i in new_text])
    new_text = "".join([x for x in new_text if ord(x) < 128])
    new_text = re.sub(r'[^\x00-\x7F]+', ' ', new_text)
    new_text = new_text.rstrip('\r\n')
    new_text = new_text.strip('\n')
    new_text = new_text.strip('\r')
    new_text = new_text.strip('\t')
    new_text = new_text.replace('\n', '')
    new_text = new_text.replace('\r', '')
    new_text = new_text.replace('\t', '')
    new_text = filter(lambda x: x in string.printable, new_text)
    new_text = "".join(list(new_text))

    return new_text

是否有一些工具可以准确地告诉我这个有问题的角色是什么,然后找到一个替换它的方法?

我这样打开文件(.csv保存为UTF-8)

f_csv_in = open(csv_in, "r", encoding="utf-8")

下面是两行,应该是一个问题非ascii字符可见。

这两行应该是一行。注意第37行末尾的$,第38行以^ I ^ I开头。

vi显示的部分问题是,第37行有一个新行$,我不希望它出现。这应该是一行。

37 Cancelled,01-19-17,,basket,00-00-00,00-00-00,,,,98533,SingleSource,,,17035 Cherry Hill Dr,"L/o 1-19-17 @ 11:45am$
38 ^I^IVictorville",SAN BERNARDINO,CA,92395,,,,,0,,,,,Lock:6111 ,,,No,No,,0.00,0.00,No,01-19-17,0.00,0.00,,01-19-17,00-00-00,,provider,,,Unread,00-00-00,,$
python-3.x csv non-ascii-characters
3个回答
0
投票

删除非ascii字符的简单方法可能是:

new_text = "".join([c for c in text if c.isascii()])

注意:如果您正在从文件中读取此文本,请确保使用正确的编码读取它


0
投票

在不可打印字符的情况下,内置字符串模块有一些过滤掉不可打印或非ascii字符的方法,例如。与isprintable()功能。 下面介绍一次过滤整个字符串的简明方法

>>> import string
>>>
>>> str1 = '\nsomestring'
>>> str1.isprintable()
False
>>> str2 = 'otherstring'
>>> str2.isprintable()
True
>>>
>>> res = filter(lambda x: x in string.printable, '\x01mystring')
>>> "".join(list(res))
'mystring'

这个问题过去在SO上有一些discussion,但是有很多方法可以做,所以我理解它可能会令人困惑,因为你可以使用从正则表达到str.translate()的任何东西

人们可以做的另一件事是看看Unicode Categories,并根据你需要的符号集筛选出你的数据。


0
投票

看起来好像你有一个包含引用值的csv文件,这些值是嵌入式逗号或换行符,必须用引号括起来,以便csv读者正确处理它们。

如果您查看示例数据,您可以看到在第一行末尾有一个开放的双引号但没有结束双引号,在第二行没有开放双引号的结束双引号,表示引号包含带有嵌入式换行符的值。

线条被分成两部分的事实可能是用于查看它们的应用程序的人工制品,或者是处理它们的代码:如果软件不理解csv引用它将假设每个换行符表示一个新行。

目前还不清楚这在数据库中究竟出现了什么问题,但引号字符(尤其是不匹配的引号)很可能会导致问题,特别是如果数据在插入之前没有被正确转义。

此代码段重写文件,删除嵌入的逗号,换行符和制表符,并指示编写者不引用任何值。如果找到需要转义的值,它将失败并显示错误消息_csv.Error: need to escape, but no escapechar set。根据您的数据,您可能需要调整正则表达式模式。

with open('lines.csv') as f, open('fixed.csv', 'w') as out:
    reader = csv.reader(f)
    writer = csv.writer(out, quoting=csv.QUOTE_NONE)
    for line in reader:
        new_row = [re.sub(r'\t|\n|,', ' ', x) for x in line]
        writer.writerow(new_row)
© www.soinside.com 2019 - 2024. All rights reserved.