我有几行文字。第一行是标题行,随后的每一行代表数据字段,每个值都用逗号分隔。每行中包含一到三个美元值,范围从个位数美元值($ 4.50)到三位数($ 100,000.34)。它们也被引号包围。
206360941,5465685679,"$4,073.77",567845676547,"$88,457.21",34589309683
我需要消除货币价值的引号和美元符号以及内部的逗号。需要保留小数点的句点分隔符,因此“ $ 6,801.56”变为6801.56
我已经使用正则表达式消除了美元符号和引号-
with open("datafile.csv", "r") as file:
data = file.readlines()
for i in data:
i = re.sub('[$"]', '', i)
然后使数据看起来像7545245,6,801.56,3545647
因此,如果我用逗号分开,则会将较大的值一分为二。
['206360941,5465685679,4,073.77,567845676547,88,457.21,34589309683']
我曾考虑过用引号分隔,进行更多的正则表达式并使用.join()重新加入,但事实证明,只有带逗号的货币值包含引号,没有逗号的较小值不包含引号。
此外,我知道我可以使用re.findall(r'\$\d{1,3}\,\d\d\d\.\d\d', i)
绘制数字格式,如果我打印出来,它将输出类似[$100,351.35]
的列表
我不确定在那之后该怎么办。
答案 0 :(得分:0)
我建议使用csv.reader
(如果要对每列进行其他处理,请使用csv.DictReader
)来读取文件,因为这将自动解析每列。读取文件后,您可以在每列上进行正则表达式,因此无需自己拆分行。我相信delimiter
的默认quotechar
和csv.reader
是您所需要的。
答案 1 :(得分:0)
您尝试过模块locale
吗?与How do I use Python to convert a string to a number if it has commas in it as thousands separators?中一样
比正则表达式更容易。
答案 2 :(得分:0)
首先,您可以删除引号内的所有逗号。
伪代码可能类似于:
s = Your String
insideQuotes = false;
charIndex = 0;
while (c = nextChar() != null){
if(c == "\""){
insideQuotes = !insideQuotes;
}else if(insideQuotes && c == ","){
s.removeAt(charIndex, "");
charIndex--;
}
}
现在报价内不再有逗号,您只需要删除美元符号和报价本身即可!
希望有帮助!
答案 3 :(得分:0)
这似乎可行:
>>> data = '206360941,5465685679,"$4,073.77",567845676547,"$88,457.21",34589309683'
>>> re.findall(r'"\$((\d+),)*(\d+)(\.\d+)"', data)
[('4,', '4', '073', '.77'), ('88,', '88', '457', '.21')]
>>> re.sub(r'"\$((\d+),)*(\d+)(\.\d+)"', r'\2\3\4', data)
'206360941,5465685679,4073.77,567845676547,88457.21,34589309683'
这个想法是获取小数点前后的数据,并保留小数点后的数据。然后,假设第一个组与第二个组相同,只需用除第一个组以外的所有组的内容替换。如果逗号不止一个,则可能需要一种更动态的方法。
这就是为什么您需要这个((\d+),)*
组的原因,该组捕获一个子组和一个逗号。您应该将整个组替换为子组。