用于检测csv文件中数字包含逗号的无效行的正则表达式

2024-05-16 11:20:04 发布

您现在位置:Python中文网/ 问答频道 /正文

下面是我的文件中的示例行。每行有3个数字字段。有些数字带有逗号,并被引用。有些行有多余的空逗号(文件是从PDF中提取表格数据输出的),我试图检测并删除有效3字段匹配左侧或右侧多余的空字段

"3,33","4,03","12,23" - valid  
2,,"3,23"             - valid  
,,"3,13",1,6 - invalid - remove first 2 commas   
,1,,"3,987", - invalid - remove comma at beginning and end  

这就是我所拥有的-(([0-9,]*,){3}) 但在努力找出如何匹配可能围绕数字的引号,也可能不围绕数字

基本上,我不清楚如果检测到一个报价,那么如何查找结束报价,如果没有,如何不查找任何结束报价。 谢谢你的帮助

(我正在使用Sublimitext 3进行搜索和替换,但如果需要,我可以使用Python进行搜索和替换。)


Tags: 文件数据示例pdf数字remove表格first
2条回答

如果您使用的是python,我建议您使用csv库:

data = '''"3,33","4,03","12,23"
2,,"3,23"
,,"3,13",1,6
,1,,"3,987",'''.split('\n')
import csv
for row in csv.reader(data):
    print(row)

输出:

['3,33', '4,03', '12,23']
['2', '', '3,23']
['', '', '3,13', '1', '6']
['', '1', '', '3,987', '']

但如果您想使用正则表达式,您可以:

(([0-9]*)|("[0-9,]*"),){3}

使用垂直管道|表示“或”,因此可以是一个数字序列[0-9]*或由引号"[0-9,]*"包围的数字和逗号

您的字段内容可能是:

  • 空的
  • 整数\d+
  • 带引号的十进制数"\d+,\d+"

这可以表示为(|\d+|"\d+,\d+")。您需要其中三个,逗号分隔:

(|\d+|"\d+,\d+"),(|\d+|"\d+,\d+"),(|\d+|"\d+,\d+")

(你可以用(|\d+|"\d+,\d+")(,(|\d+|"\d+,\d+")){2}来处理重复,但是同样的事情重复三次就更容易理解了)

请注意,这将假定最后一个字段为“空”,因为这足以匹配您的定义。因此,我们需要将其锚定到线路的起点和终点:

^(|\d+|"\d+,\d+"),(|\d+|"\d+,\d+"),(|\d+|"\d+,\d+")$

这将仅与有效行匹配

根据您的解释,开头和结尾可能有额外的逗号,但没有其他字符,因此:

^,*(|\d+|"\d+,\d+"),(|\d+|"\d+,\d+"),(|\d+|"\d+,\d+"),*$

<>这与所有的线匹配,但不能给你真正关心的东西,中间的“好”部分。为此,可以使用组(使用括号)。但是,我们已经在使用组,用于|替代方案,因此我们需要添加?:以使它们不被捕获:

^,*(?:|\d+|"\d+,\d+"),(?:|\d+|"\d+,\d+"),(?:|\d+|"\d+,\d+"),*$

现在,您可以将您关心的部分包装在捕获组中,为我们提供最终的regexp:

^,*((?:|\d+|"\d+,\d+"),(?:|\d+|"\d+,\d+"),(?:|\d+|"\d+,\d+")),*$

搜寻及;在regexp模式下,用此regexp替换搜索,用\1替换替换值

如果多个字段为空,则可能存在多个可能的解决方案。如果三个值中的第一个和最后一个值从不为空,则可以相应地调整regexp。如果是,这将选择一组有效值,这些值可能不是您想要的。例如,如果您有:

,,1,"2,3",,

那么,1,"2,3(empty,1,2.3)和1,"2,3",(1,2.3,empty)都是可能的解决方案。默认情况下,您将得到第二个结果,因为*是贪婪的,即第一个,*将尝试“吃”尽可能多的逗号,而不会使匹配失败。您可以添加这样一个问号:,*?使匹配成为“懒惰”或“非贪婪”,那么它只需要使用所需数量的逗号(产生第一个结果)

相关问题 更多 >