8

我想使用 python CSV 阅读器,但我想保留引号。这就是我想要的:

>>> s = '"simple|split"|test'
>>> reader = csv.reader([s], delimiter='|', skipinitialspace=True)
>>> reader.next()
['"simple|split"', 'test']

但我实际上得到:

['simple|split', 'test']

在我的情况下,我希望引用的字符串仍然被引用。

我知道 CSV 阅读器正在按预期工作,并且我的用例是对它的滥用,但是有什么方法可以让我按照自己的意愿弯曲它吗?还是我必须编写自己的字符串解析器?

4

2 回答 2

5

您将不得不编写自己的解析器,因为支持解析和引用的模块部分位于 C 方面,特别是parse_process_char位于Modules/_csv.c

    else if (c == dialect->quotechar &&
             dialect->quoting != QUOTE_NONE) {
        if (dialect->doublequote) {
            /* doublequote; " represented by "" */
            self->state = QUOTE_IN_QUOTED_FIELD;
        }
        else {
            /* end of quote part of field */
            self->state = IN_FIELD;
        }
    }
    else {
        /* normal character - save in field */
        if (parse_add_char(self, c) < 0)
            return -1;
    }

“字段的引用部分结束”部分是你的双引号。另一方面,您可能能够取消该else条件并重建 python 源代码。然而,老实说,这并不是所有可以维护的。

编辑:对不起,我的意思是从最后一个添加位,else所以self->state = IN_FIELD它添加了引号。

于 2013-03-08T13:58:41.060 回答
2

我不明白你是否清楚地了解你想要获得的东西。
你说“我知道(...)我的用例是一种滥用”
但滥用意味着存在使用的可能性。
但是,在您的情况下,没有可能的用途,您“描述”的内容是不可能的,因为传递给 CSV 解析器的内容必须是有效的 CSV 格式,而您的不是。

在 CSV 有效字符串中,大多数字符是信息,一些字符是解释字符串以提取信息所必需的元信息。
您描述的是您希望字符"应该完全属于信息类别和元信息类别。就像有人想用左手抓住他/她的左手......

您的字符串出现此问题,因为它不是来自读取 CSV 文件的字符串。这是一个按原样编写的字符串。
从 CSV 文件的读取中获取这样的字符串是不可能的,因为它不可能像这样写在 CSV 文件中。
如果写入 CSV 文件,'"simple|split"|test'可以写入

  • """simple|split"""|test
    设置doublequote为 True,默认

  • #"simple#|split#"|test
    doublequote = False, escapechar = '#'

.

如果你想像你描述的那样提取信息,你不必创建解析器,你只需要使用一个已经存在的工具:

import re

reg = re.compile('".*?"|[^|]+')

print reg.findall('yoo|"simple|split"|test|end"pos|hu')

结果

['yoo', '"simple|split"', 'test', 'end"pos', 'hu']
于 2013-03-08T16:44:58.467 回答