源数据如下所示。第四条记录中的一个字段具有多行字符串。
i1|j1|k1|l1|m1
i2|j2|k2|l2|m2
i3|j3|k3|l3|m3
i4|j4|k4|"l4 is
multiline data
multiline data"|m4
i5|j5|k5|l5|m5
我正在通过sc.wholeTextFiles
rdd= sc.wholeTextFiles("file.csv").flatMap(lambda x: x[1].split("\n"))
print rdd.take(100)
print rdd.count()
rdd.take(100)
的输出:
[u'i1|j1|k1|l1|m1', u'i2|j2|k2|l2|m2', u'i3|j3|k3|l3|m3', u'i4|j4|k4|"l4 is', u'multiline data', u'multiline data"|m4', u'i5|j5|k5|l5|m5', u'']
rdd.count()
的输出
8
这里的问题是multiline
数据被视为新记录。因此,计数也增加了。如何将multiline
数据视为列的一个字符串值(以l4
开头)?
答案 0 :(得分:1)
一种方法是使用高级正则表达式表达式(仅受更新的regex
模块支持)忽略双引号中的换行符:
"[^"]*"(*SKIP)(*FAIL)|\n
读为
"[^"]*"(*SKIP)(*FAIL) # match anything between double quotes and "forget" the match
| # or
\n # match a newline
Python
中,应为:
import regex as re
data = """i1|j1|k1|l1|m1
i2|j2|k2|l2|m2
i3|j3|k3|l3|m3
i4|j4|k4|"l4 is
multiline data
multiline data"|m4
i5|j5|k5|l5|m5"""
rx = re.compile(r'"[^"]*"(*SKIP)(*FAIL)|\n')
lines = rx.split(data)
print(lines)
这会产生
['i1|j1|k1|l1|m1', 'i2|j2|k2|l2|m2', 'i3|j3|k3|l3|m3', 'i4|j4|k4|"l4 is\nmultiline data\nmultiline data"|m4', 'i5|j5|k5|l5|m5']
请注意,尽管转义的引号(\"
)会破坏该机制。