正如 cmets 中所说,您可以使用“损坏”的 csv 行来制定语法,并将结果输出提供给 pandas DataFrame。
以下内容当然可以优化,但可能会给您一个想法:
from parsimonious.grammar import Grammar
from parsimonious.nodes import NodeVisitor
import pandas as pd
broken_garbage = """
1, (2, 3), 4
colAVal, (colBVal_1, colBVal_2), colCVal,
this, one, right
234,(123,456),789
"""
grammar = Grammar(
r"""
content = garbage? line+
line = entry+ newline?
entry = value sep?
value = word / (lpar word sep word rpar)
lpar = "("
rpar = ")"
word = ~"\w+"
sep = ws? "," ws?
ws = ~"[\t ]+"
newline = ~"[\r\n]+"
garbage = (ws / newline)+
"""
)
class BrokenVisitor(NodeVisitor):
def generic_visit(self, node, visited_children):
return visited_children or node
def visit_value(self, node, visited_children):
child = visited_children[0]
if isinstance(child, list):
_, value1, _, value2, _ = child
return (value1.text, value2.text)
else:
return child.text
def visit_entry(self, node, visited_children):
values, _ = visited_children
return values
def visit_line(self, node, visited_children):
content = visited_children[0]
return [item for item in content]
def visit_content(self, node, visited_children):
return visited_children[1]
tree = grammar.parse(broken_garbage)
broken = BrokenVisitor()
values = broken.visit(tree)
df = pd.DataFrame(values, columns=["one", "two", "three"])
print(df)
这产生
one two three
0 1 (2, 3) 4
1 colAVal (colBVal_1, colBVal_2) colCVal
2 this one right
3 234 (123, 456) 789
查看反映您的结构的语法。
BrokenVisitor 类访问每个语法块并将行作为列表返回。然后将此结果输入
pandas.DataFrame 构造函数。
或者,您可以使用支持
\K 的较新的
regex module,并将括号中的所有逗号替换为另一个字符:
\([^,()]+\K,
在Python 这可能是:
import regex as re
rx = re.sub(r'\([^,()]+\K,')
new_string = rx.sub('@', old_string)
之后,您可以将新字符串直接输入pandas.read_csv()。
见a demo on regex101.com。