我有一个文件,.csv文件中的一些行由于行中某些字段中的时髦字符而阻塞了数据库导入。
我搜索了一些关于如何在Python3中替换非ascii字符的文章,但都不起作用。
当我在vi和do:set列表中打开文件时,在一行的末尾不应该有$,在下一行的开头有^I^I。这两条线应该是一条连接线,而不是^I。我知道$是"\n"行的末尾,并试图替换它们,但什么都不起作用。
我不知道^I代表什么,可能是一个标签。
我尝试过这个功能,但没有用:
def remove_non_ascii(text):
new_text = re.sub(r"[ntr]", "", 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('rn')
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,,$
删除非ascii字符的一个简单方法可以是:
new_text = "".join([c for c in text if c.isascii()])
注意:如果你正在从文件中读取此文本,请确保使用正确的编码进行读取
在不可打印字符的情况下,内置字符串模块有一些过滤不可打印或非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上进行过一些讨论,但有很多方法可以做事情,所以我理解它可能会令人困惑,因为你可以使用从正则表达式到str.translate()
的任何东西
可以做的另一件事是查看Unicode类别,并根据所需的符号集筛选出数据。
看起来好像您有一个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)
使用re
、python
过滤不可打印ASCII字符的另一种方法:
import re
import string
string_with_printable = re.sub(f'[^{re.escape(string.printable)}]', '', original_string)
re.escape
转义给定模式中的特殊字符。