如何在python中为包含逗号分隔值的文本编写正则表达式?

时间:2016-09-07 23:05:51

标签: python regex csv

我正在尝试在python中编写一个正则表达式,从一行看起来像这样的F1到F8字段:

LineNumber(digits): F1, F2, F3, ..., F8;

F1F8可以使用小写/大写字母和连字符。

例如:

Header
Description
21: Yes, No, Yes, No, Ye-s, N-o, YES, NO;
Footer

到目前为止我尝试过的是 matched = re.match(r'\d+: ([a-zA-Z-]*, ){7}(.*);', line)与上述格式的行匹配。但是,当我致电matched.groups()打印匹配的字段时,我只会获得F7,F8,而预期的输出是包含F1,F7,的列表F8

我对这个正则表达式有几个问题:

  1. 我猜groups()方法返回使用(...)在正则表达式中分组的字段。为什么我在使用(...)分组并且匹配正则表达式时输出中的F1到F6?

  2. 我可以编写什么更好的正则表达式将,从F1排除到F7? (非常感谢建议的正则表达式的简短解释)

2 个答案:

答案 0 :(得分:1)

>>> pat = re.compile("""\s+ # one or more spaces
                      (.*?) # the shortest anything (capture)
                      \s*   # zero or more spaces
                      [;,]  # a semicolon or a colon
                     """,re.X)
>>> pat.findall("LineNumber(digits): F1, F2, F3, F4, F5, F6, F7, F8;")
['F1', 'F2', 'F3', 'F4', 'F5', 'F6', 'F7', 'F8']

答案 1 :(得分:0)

当你有一个像(pattern){number}这样的结构时,虽然它匹配多个实例,但只存储最后一个实例。换句话说,即使您多次解析,每个()也会获得一个存储桶,在这种情况下,最后一个实例是保留的存储。请注意,您将获得所有括号对的存储桶,即使它们未被使用,例如匹配(a(b)?c)?d的{​​{1}}。

如果您知道要预期的项目数量,那么您可以在很长一段时间内完成正则表达式:

d

这样,由于您有8组括号,因此\d+: *([a-zA-Z-]+) *, *([a-zA-Z-]+) *, *([a-zA-Z-]+) *, *([a-zA-Z-]+) *, *([a-zA-Z-]+) *, *([a-zA-Z-]+) *, *([a-zA-Z-]+) *, *([a-zA-Z-]+) *;数组中有8个项目。另外,我们没有捕捉字段之间的空格和逗号。

鉴于您的字符串是CSV,您可能最好以不同方式解析它并在逗号上拆分而不是尝试使用单个正则表达式来匹配整行。