Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/323.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
python3中带有多字符分隔符的csv读取器_Python_Python 3.x_Csv - Fatal编程技术网

python3中带有多字符分隔符的csv读取器

python3中带有多字符分隔符的csv读取器,python,python-3.x,csv,Python,Python 3.x,Csv,除了使用csv模块以流式方式读取python3中的csv文件外,还有其他方法吗?当前我的数据如下所示: "field1"::"field2"::"field3"\x02\n "1"::"hi\n"::"3"\x02\n "8"::"ok"::"3"\x02\n 分隔符是两个字符,:(csv模块只接受一个字符分隔符),行分隔符也包含两个字符,\x02\n。是否有任何CSVReader可以在流模式下用于python,并且能够支持这一点 下面是我尝试做的一个例子: >>> impo

除了使用
csv
模块以流式方式读取python3中的csv文件外,还有其他方法吗?当前我的数据如下所示:

"field1"::"field2"::"field3"\x02\n
"1"::"hi\n"::"3"\x02\n
"8"::"ok"::"3"\x02\n
分隔符是两个字符,
(csv模块只接受一个字符分隔符),行分隔符也包含两个字符,
\x02\n
。是否有任何CSVReader可以在流模式下用于python,并且能够支持这一点

下面是我尝试做的一个例子:

>>> import csv
>>> s = ''''"field1"::"field2"::"field3"\x02\n\n"1"::"hi\n"::"3"\x02\n\n"8"::"ok"::"3"\x02\n'''
>>> csvreader=csv.reader(s, delimiter='::', lineterminator='\x02\n')
Traceback (most recent call last):
  File "<console>", line 1, in <module>
TypeError: "delimiter" must be a 1-character string
导入csv >>>s=''''''字段1:''字段2:''字段3'\x02\n\n“1:''嗨\n:''3'\x02\n\n“8:''好:''3'\x02\n'' >>>csvreader=csv.reader(s,分隔符='::',行终止符='\x02\n') 回溯(最近一次呼叫最后一次): 文件“”,第1行,在 TypeError:“分隔符”必须为1个字符的字符串
加载pandas只是为了读取此csv似乎有些过分,因此我想看看还有哪些其他选项。

正如您所发现的,csv库不适合该数据格式。您可以预先解析数据。例如,以下方法应该有效:

from io import StringIO
import csv

s = '''"field1"::"field2"::"field3"\x02\n\n"1"::"hi\n"::"3"\x02\n\n"8"::"ok"::"3"\x02\n'''

def csv_reader_alt(source):
    return csv.reader((line.replace('\x02', '').replace('::', ':') for line in source), delimiter=':')    

for row in csv_reader_alt(StringIO(s)):
    if row:
        print(row)
为您提供以下输出:

['field1','field2','field3']
['1','hi\n','3']
['8','ok','3']

@MartinEvans在他的回答中展示了一种很好的方法

以下是使用自定义分隔符(使用自定义生成器实现)通过正确的文件处理从文件(而不是从内存中的字符串)读取的代码:


这对您有用吗?

如果您能够控制此csv的格式,我会切换到单个字符和不同的行分隔符,但我相信使用just open和re就足够了。您是说您希望在同一个过程中使用两个分隔符分隔数据吗?另外,您是否正在使用
csv.reader
?你可以发布你目前试图用来清理这些数据的代码部分吗?这里有一个相关的Q/a,但需要熊猫——对于这样一个小功能来说,这似乎是一个巨大的依赖:@BrianPeterson同意——还有其他选择吗?@Jaba
re
非常棘手——有转义字符、引号字符,等等。我不想尝试也不想那样做。谢谢你。请参阅更新的问题,逐行读取数据并不是那么简单。@DavidL要从您的小示例中分辨出确切的格式有点困难,但我现在已经演示了如何在将数据传递给正常的
csv.reader()之前预解析数据。也许链接到实际的CSV文件将有助于测试。
def get_line(file, delimiter='\n', bufsize=4096):
    # https://stackoverflow.com/a/19600562/9225671
    buf = ''
    while True:
        chunk = file.read(bufsize)
        if len(chunk) == 0:
            # end of file has been reached; serve the remaining data and exit
            yield buf
            return

        buf += chunk
        line_list = buf.split(delimiter)

        # don't serve the last part yet, first we need to read more chunks from the file
        buf = line_list.pop(-1)

        for line in line_list:
            yield line

if __name__ == '__main__':
    with open('my_file.csv') as f:
        for line in get_line(f, delimiter='\x02\n'):
            if len(line) > 0:
                parts = line.split('::')
                print(parts)
                print([
                    e.strip('"')
                    for e in parts])