我試圖使用pyparsing
解析一個CSV用:括號之間如何解析CSV用括號和缺失值之間逗號
- 逗號(或托架等):「一個(1,2) ,b「應返回列表[」a(1,2)「,」b「]
- 缺失值:」a,b ,, c「應返回列表['a','b' ,'','c','']
我工作的解決方案,但它似乎「髒」。大體上,Optional
內唯一可能的原子公司之一。我認爲可選應該獨立於原子。也就是說,我覺得它應該在其他地方放,例如在delimitedList
可選參數,但在我的試驗和錯誤,這是隻有工作,是有意義的地方。它可能在任何可能的原子中,所以我選擇了第一個。
另外,我不完全瞭解什麼originalTextFor
是做什麼,但如果我刪除它,它停止工作。
工作例如:
import pyparsing as pp
# Function that parses a line of columns separated by commas and returns a list of the columns
def fromLineToRow(line):
sqbrackets_col = pp.Word(pp.printables, excludeChars="[],") | pp.nestedExpr(opener="[",closer="]") # matches "a[1,2]"
parens_col = pp.Word(pp.printables, excludeChars="(),") | pp.nestedExpr(opener="(",closer=")") # matches "a(1,2)"
# In the following line:
# * The "^" means "choose the longest option"
# * The "pp.Optional" can be in any of the expressions separated by "^". I put it only on the first. It's used for when there are missing values
atomic = pp.originalTextFor(pp.Optional(pp.OneOrMore(parens_col)))^pp.originalTextFor(pp.OneOrMore(sqbrackets_col))
grammar = pp.delimitedList(atomic)
row = grammar.parseString(line).asList()
return row
file_str = \
"""YEAR,a(2,3),b[3,4]
1960,2.8,3
1961,4,
1962,,1
1963,1.27,3"""
for line in file_str.splitlines():
row = fromLineToRow(line)
print(row)
打印:
['YEAR', 'a(2,3)', 'b[3,4]']
['1960', '2.8', '3']
['1961', '4', '']
['1962', '', '1']
['1963', '1.27', '3']
這是這樣做的正確方法?是否有一個「乾淨」的方式來使用裏面的第一個原子的Optional
?
對於數值的分析時轉換,將'atomic'更改爲:'atomic = pp.pyparsing_common.number | pp.originalTextFor(...等)。 – PaulMcG