6

我需要在 CSV 文件中搜索以未终止的双引号字符串结尾的行。

例如:

1,2,a,b,"dog","rabbit

会匹配而

1,2,a,b,"dog","rabbit","cat bird"
1,2,a,b,"dog",rabbit

不会。

我对正则表达式的经验非常有限,我唯一能想到的就是

"[^"]*$

但是,这与行尾的最后一个引号相匹配。

这将如何完成?

4

4 回答 4

5

假设引号不能被转义,您需要测试引号的奇偶性(确保它们的数量是偶数而不是奇数)。正则表达式非常适合:

^(([^"]*"){2})*[^"]*$

这将匹配具有偶数个引号的所有行。您可以反转所有奇数字符串的结果。或者您可以([^"]*")在开头添加另一部分:

^[^"]*"(([^"]*"){2})*[^"]*$

同样,如果您可以访问不情愿的运算符而不是贪婪的运算符,则可以使用看起来更简单的表达式:

^((.*"){2})*.*$         #even
^.*"((.*"){2})*.*$      #odd

现在,如果引号可以转义,这完全是一个不同的问题,但方法是相似的:确定未转义引号的奇偶性。

于 2010-05-25T15:59:45.560 回答
4

假设字符串不能包含",则需要匹配具有奇数个引号的字符串,如下所示:

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

请注意,这很容易受到 DDOS 攻击。

这将匹配零个或多个未引用的运行集,然后是引用的字符串。

于 2010-05-25T15:59:41.730 回答
1

试试这个:

".+[^"](,|$)

这匹配一个引号(行中的任何位置),然后(贪婪地)在行尾或逗号之前添加另一个引号之外的任何内容。

净影响是它只会匹配带有悬空引用字符串的行。

我认为它甚至可以不受“嵌套扩展攻击”的影响(我们确实生活在一个非常危险的世界......)

于 2010-05-25T16:39:24.833 回答
0

为避免“嵌套扩展”:

egrep -v '^[^"]*("[^"]*"[^"]*)*[^"]*$' my_file
于 2010-05-25T16:05:04.797 回答