python - 如何在单个字段中读取带有多个引号分隔符的 csv?

标签 python csv

我希望能够拆分包含多次引用的定界符的字符串。是否存在使用 csv 模块处理此类字符串的参数?还是有其他处理方式?

text = '"a,b"-"c,d","a,b"-"c,d"'
next(csv.reader(StringIO(text), delimiter=",", quotechar='"', quoting=csv.QUOTE_NONE))

预期输出:['"a,b"-"c,d"', '"a,b"-"c,d"']

实际输出:['"a', 'b"-"c', 'd"', '"a', 'b"-"c', 'd"']

编辑: 上面的例子是简化的,但显然过于简化了,因为一些评论提供了简化版本的解决方案,而不是完整版本。下面是我要处理的实际数据。

import csv
text = '"3-Amino-1,2,4-triazole"-text-0-"3-Amino-1,2,4-triazole"-CD-0,"3-Amino-1,2,4-triazole"-text-0-"3-Amino-1,2,4-triazole"-LS-0'
next(csv.reader(StringIO(text), delimiter=",", quotechar='"', quoting=csv.QUOTE_NONE))

预期输出

[
  '"3-Amino-1,2,4-triazole"-text-0-"3-Amino-1,2,4-triazole"-CD-0',
  '"3-Amino-1,2,4-triazole"-text-0-"3-Amino-1,2,4-triazole"-LS-0'
]

实际输出

[
  '"3-Amino-1',
  '2',
  '4-triazole"-text-0-"3-Amino-1',
  '2',
  '4-triazole"-CD-0','"3-Amino-1',
  '2', '4-triazole"-text-0-"3-Amino-1',
  '2',
  '4-triazole"-LS-0'
]

最佳答案

我只会回答你问题的第一部分:使用内置的 csv 模块无法做到这一点。

查看CPython源码,quotechar选项为only processed在字段的开头:

    case START_FIELD:
        /* expecting field */
        ...
        else if (c == dialect->quotechar &&
                 dialect->quoting != QUOTE_NONE) {
            /* start quoted field */
            self->state = IN_QUOTED_FIELD;
        }
        ...
        break;

在字段内,there is no such check :

    case IN_FIELD:
        /* in unquoted field */
        if (c == '\n' || c == '\r' || c == '\0') {
            /* end of line - return [fields] */
            if (parse_save_field(self) < 0)
                return -1;
            self->state = (c == '\0' ? START_RECORD : EAT_CRNL);
        }
        else if (c == dialect->escapechar) {
            /* possible escaped character */
            self->state = ESCAPED_CHAR;
        }
        else if (c == dialect->delimiter) {
            /* save field - wait for new field */
            if (parse_save_field(self) < 0)
                return -1;
            self->state = START_FIELD;
        }
        else {
            /* normal character - save in field */
            if (parse_add_char(self, module_state, c) < 0)
                return -1;
        }
        break;

当解析器处于 IN_QUOTED_FIELD 状态时,会检查 quotechar;但是,在遇到引号时,它会返回到 IN_FIELD 状态,表明我们在未引号的字段中。所以这是可能的:

>>> import csv
>>> import io
>>> print(next(csv.reader(io.StringIO('"a,b"cd,e'))))
['a,bcd', 'e']

但是一旦解析器到达初始引用部分的末尾,它会将任何后续引用视为数据的一部分。我不知道这种行为是否符合任何(成文或未成文的)CSV 规范,或者它是否只是一个错误。

关于python - 如何在单个字段中读取带有多个引号分隔符的 csv?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68055766/

相关文章:

python - BeautifulSoup + URLLib2 没有从目标中提取所有 XML

python - matplotlib 使日期的轴刻度标签变为粗体

python - 这种从具有 2 个类属性且 BeautifulSoup 的标签获取项目的方法是否正确?

Python 生成的 RSS : outputting raw HTML?

python - 使用 python 在同一文件中将逗号替换为管道分隔符

java - 如何将 .CSV 文件导入 Drools

python - 将我的列转换为小数点后两位

ruby-on-rails - 在 Ruby 中解析 csv 文件

python - 使用 pandas group by 从最大到最小的顺序排序

spring - 如何使用FlatFileItemReader和 block 跳过CSV中的空白行