Python 如何防止csv嗅探器认为连字符是UNICODE 8722而不是45?

Python 如何防止csv嗅探器认为连字符是UNICODE 8722而不是45?,python,csv,Python,Csv,我正在做这件事,将试图找出csv格式,并询问最终用户,如果它是正确的。我开始使用时区进行测试,我的测试输入如下所示 "\r\n".join( ( "timestamp;col1;col2", "2020-01-22T00:14:47-04:00;1;6.1", &

我正在做这件事,将试图找出csv格式,并询问最终用户,如果它是正确的。我开始使用时区进行测试,我的测试输入如下所示

            "\r\n".join(
                (
                    "timestamp;col1;col2",
                    "2020-01-22T00:14:47-04:00;1;6.1",
                    "2020-02-23T01:15:47-04:00;2;7.1",
                    "2020-02-24T01:15:47-04:00;3;8.1",
                    "2020-02-25T01:15:47-04:00;4;9.1",
                    "2020-02-26T01:15:47-04:00;5;0.",
                )
            ).encode()
为了弄清楚我是怎么做的

csv.Sniffer().sniff(lookup_row, self.allowed_delimiters)
我用

csv.reader(opened_csv, dialect=dialect)
这是有趣的部分。复制时,粘贴第一个时间戳并将其解析为datetime

from dateutil import parser

a = '2020-01-22T00:14:47-04:00'
found_val = parser.parse(a)
它正确地返回日期时间。但是当我通过sniff运行这个输入时,csv.reader和迭代test
dateutil
中的行无法解析它

b = '2020-01-22T00:14:47−04:00'  # <-- in my test case
所以当我仔细看的时候

a_ord = [ord(char) for char in a]  # [50, 48, 50, 48, 45, 48, 49, 45, 50, 50, 84, 48, 48, 58, 49, 52, 58, 52, 55, 45, 48, 52, 58, 48, 48]
b_ord = [ord(char) for char in b]  # [50, 48, 50, 48, 45, 48, 49, 45, 50, 50, 84, 48, 48, 58, 49, 52, 58, 52, 55, 8722, 48, 52, 58, 48, 48]
差异是时区附近的
-
符号。显然,“原始”复制粘贴会产生负号,即UNICODE
45
,而
sniffer
认为(?)是
8722

我的脑子被炸了,特别是因为这个单元格中的其他连字符被认为是
45

由于这是一个特例场景,我只关心此列的正确解析,因此替换此字符(如果找到)是最好的方法吗

或者我可以在sniffer中定义一个错误的字符/限制UNICODE范围吗

是否应将其视为
dateutil
中的错误

是否应将其视为dateutil中的错误

我不会那么说。我对dateutil一无所知,但我想说的是,您只是没有利用可用的功能

查看的文档,您似乎可以传递一个可选对象,该对象描述构成可接受输入的内容

具体来说,我认为您需要查看,这似乎是一个可接受的分隔符列表,默认情况下如下所示:

JUMP= [' ', '.', ',', ';', '-', '/', "'", 'at', 'on', 'and', 'ad', 'm', 't', 'of', 'st', 'nd', 'rd', 'th']

所以,我猜,你所要做的就是传入这些
parserinfo
对象中的一个,其中有一个自定义的
跳转
,其中包括你的特殊连字符。

我想让它在读级可解析,因为我不想逐个替换数百万个单元格中的字符,但出于某种原因,我还没有想过仅仅将这个奇怪的字符添加到
parserinfo
。我现在就试试。谢谢。遗憾的是它没有按预期工作<代码>b='2020-01-22T00:14:47−04:00'#@TomWojcik预期的结果是什么?对不起,我不清楚。
2020-01-22 00:14:47
。现在它认为偏移量是my
datetime
对象中无法复制的
time
。如何打开csv文件?为什么要将测试数据编码为字节对象?这是我从API获得的原始输入,并将其保存到Django中的
FileField
。要加载它,我用
rb
打开有效负载,解码并写入
StringIO
。然后将
csv.reader
与嗅出的方言一起使用。使用您的测试输入->编码->解码->放入StringIO->嗅探->csv.reader,我得到了正常的
-
。此外,我还没有听说csv阅读器或嗅探器会改变csv单元格的内容。可能是其他原因改变了你的约会。e、 我不认为是Django,但我不知道是什么。无论如何,我真的很感激你能深入研究这个问题。@Wups我从一个网站上复制了时区,每个时区有一个偏移量,这里有一个奇怪的连字符!你是对的。没有什么能改变这一切。对不起,浪费了你的时间。
JUMP= [' ', '.', ',', ';', '-', '/', "'", 'at', 'on', 'and', 'ad', 'm', 't', 'of', 'st', 'nd', 'rd', 'th']