用于 CSV 拆分的正则表达式,包括多个双引号

Posted

技术标签:

【中文标题】用于 CSV 拆分的正则表达式,包括多个双引号【英文标题】:Regex for CSV split including multiple double quotes 【发布时间】:2015-11-25 03:04:02 【问题描述】:

我有一个包含文本的 CSV 列数据。每行用双引号分隔"

一行中的示例文本与此类似(注意:新行和每行之前的空格是有意的

"Lorem ipsum dolor sit amet, 
 consectetur adipisicing elit, sed do eiusmod
 tempor incididunt ut labore et dolore magna 
 aliqua. Ut ""enim ad"" minim veniam,
 quis nostrud exercitation ullamco laboris nisi 
 ut aliquip ex ea commodo
 consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
 cillum dolore eu fugiat ""nulla pariatu"""
"ex ea commodo
 consequat. Duis aute irure ""dolor in"" reprehenderit 
 in voluptate velit esse
 cillum dolore eu fugiat nulla pariatur. 
 Excepteur sint occaecat cupidatat non
 proident, sunt in culpa qui officia deserunt 
 mollit anim id est laborum."

以上代表2个后续行。

我想选择每个第一个双引号 "(开始一行)和每个最后一个双引号 " 之间包含的所有文本作为单独的组

如您所见,文本中有换行符,以及随后的转义双引号 "" 这是我需要选择的文本的一部分。

我想出了这样的东西

(?s)(?!")[^\s](.+?)(?=")

但是多个双引号破坏了我想要的匹配

我是一个真正的正则表达式新手,所以我想我可能遗漏了一些非常基本的东西。不知道是否相关,但我使用的是 Sublime Text 3,所以我认为应该是 python。

我能做些什么来达到我的需要?

【问题讨论】:

【参考方案1】:

您可以使用以下正则表达式:

"[^"]*(?:""[^"]*)*"

见demo

此正则表达式将匹配一个非引号,或双引号内的两个后续双引号。

它是如何工作的?分享一张来自debuggex.com的图:

使用正则表达式,我们匹配:

" - (1) - 文字引用 [^"]* - (2, 3) - 除了引号之外的 0 个或多个字符(是的,包括换行符,这是 negated character class),如果没有,则正则表达式搜索最终的文字引号 (6) (?:""[^"]*)* - (4,5) - 0 个或多个序列: "" - (4) - 双双引号 [^"]* - (5) - 0 个或多个字符,而不是引号 " - (6) - 最后的文字引用。

这比"(?:[^"]|"")*" 工作得更快(尽管产生相同的结果),因为前者的处理是线性的,涉及的回溯要少得多。

【讨论】:

实际上,正则表达式可以在 Python 和 PCRE 引擎中使用。 Sublime Text 使用 PCRE 引擎进行搜索和替换,使用 Oniguruma 进行语法高亮。 就是这样,谢谢!你能解释一下为什么它有效吗?不匹配的标签有点让我失望,为什么它也包括断线? Meh RTFM 问题:“与点不同,negated character classes 也匹配(不可见)换行符。”还是谢谢!【参考方案2】:

如果你使用python,那么你不需要regex,你可以直接使用标准的csv library,单行内的双双引号会被自动处理。示例(对于您在上面a.csv 中发布的 csv)-

>>> import csv
>>> with open('a.csv','r') as f:
...     reader = csv.reader(f)
...     for row in reader:
...             print(row)
...
['Lorem ipsum dolor sit amet, \n consectetur adipisicing elit, sed do eiusmod\n tempor incididunt ut labore et dolore magna \n aliqua. Ut "enim ad" minim veniam,\n quis nostrud exercitation ullamco laboris nisi \n ut aliquip ex ea commodo\n consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse\n cillum dolore eu fugiat "nulla pariatu"']
['ex ea commodo\n consequat. Duis aute irure "dolor in" reprehenderit \n in voluptate velit esse\n cillum dolore eu fugiat nulla pariatur. \n Excepteur sint occaecat cupidatat non\n proident, sunt in culpa qui officia deserunt \n mollit anim id est laborum.']

这由 csv 模块正确处理,主要是因为 " 是默认的 quotechar ,因此两个 " 内的任何内容都被视为该单列的一部分,即使它的 \n 或空格等.

另外,csv 模块还有另一个参数称为 doublequote,即 -

控制出现在字段中的 quotechar 实例如何被引用。 当为 True 时,字符加倍。当为 False 时,escapechar 用作 quotechar 的前缀。默认为 True。

【讨论】:

这只有在 OP 正在为 Sublime Text 构建一些基于 Python 的插件时才有用。 这个问题有Python标签,所以我给出了一个基于python的答案。 感谢您的意见,但@stribizhev 是对的,您也是。我放置 Python 标签只是因为我知道 sublime text 是用它构建的,而且我知道(非常基本)正则表达式可以根据使用的语言更改一些函数。 +1 确实如此,因为我认为这对其他人仍然有用!

以上是关于用于 CSV 拆分的正则表达式,包括多个双引号的主要内容,如果未能解决你的问题,请参考以下文章

正则表达式用于在不被单引号或双引号包围时使用空格分割字符串

正则表达式删除由双引号划定的 CSV 字段中的双引号

正则表达式在csv中找到缺少的双引号

正则表达式从 CSV 中删除双引号

正则表达式将引号添加到不带引号的 CSV 列

正则表达式拆分 CSV