我需要在 CSV 文件中搜索以未终止的双引号字符串结尾的行。
例如:
1,2,a,b,"dog","rabbit
会匹配而
1,2,a,b,"dog","rabbit","cat bird"
1,2,a,b,"dog",rabbit
不会。
我对正则表达式的经验非常有限,我唯一能想到的就是
"[^"]*$
但是,这与行尾的最后一个引号相匹配。
这将如何完成?
我需要在 CSV 文件中搜索以未终止的双引号字符串结尾的行。
例如:
1,2,a,b,"dog","rabbit
会匹配而
1,2,a,b,"dog","rabbit","cat bird"
1,2,a,b,"dog",rabbit
不会。
我对正则表达式的经验非常有限,我唯一能想到的就是
"[^"]*$
但是,这与行尾的最后一个引号相匹配。
这将如何完成?
假设引号不能被转义,您需要测试引号的奇偶性(确保它们的数量是偶数而不是奇数)。正则表达式非常适合:
^(([^"]*"){2})*[^"]*$
这将匹配具有偶数个引号的所有行。您可以反转所有奇数字符串的结果。或者您可以([^"]*")
在开头添加另一部分:
^[^"]*"(([^"]*"){2})*[^"]*$
同样,如果您可以访问不情愿的运算符而不是贪婪的运算符,则可以使用看起来更简单的表达式:
^((.*"){2})*.*$ #even
^.*"((.*"){2})*.*$ #odd
现在,如果引号可以转义,这完全是一个不同的问题,但方法是相似的:确定未转义引号的奇偶性。
假设字符串不能包含"
,则需要匹配具有奇数个引号的字符串,如下所示:
([^"]*("[^"]*")?)*"
请注意,这很容易受到 DDOS 攻击。
这将匹配零个或多个未引用的运行集,然后是引用的字符串。
试试这个:
".+[^"](,|$)
这匹配一个引号(行中的任何位置),然后(贪婪地)在行尾或逗号之前添加除另一个引号之外的任何内容。
净影响是它只会匹配带有悬空引用字符串的行。
我认为它甚至可以不受“嵌套扩展攻击”的影响(我们确实生活在一个非常危险的世界......)
为避免“嵌套扩展”:
egrep -v '^[^"]*("[^"]*"[^"]*)*[^"]*$' my_file