Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/three.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用负lookbehind regex作为记录分隔符在Spark中读取Hadoop文件_Regex_Scala_Apache Spark_Delimiter_Rdd - Fatal编程技术网

使用负lookbehind regex作为记录分隔符在Spark中读取Hadoop文件

使用负lookbehind regex作为记录分隔符在Spark中读取Hadoop文件,regex,scala,apache-spark,delimiter,rdd,Regex,Scala,Apache Spark,Delimiter,Rdd,我有很多大型tsv文件,我正在使用ApacheSpark处理这些文件。这些文件以换行符作为记录分隔符,但每隔几千条记录,就会在列中添加以\开头的换行符转义序列 这是一个示例数据集 a b c a b c a b c a b c a b c a b c\ \ \ \ \ \ d a b c a b c 每当换行符前面有\时,这意味着这不是记录的结尾,并将继续,直到它到达一个不带\的换行符为止。我使用负查找断言将转义字

我有很多大型tsv文件,我正在使用ApacheSpark处理这些文件。这些文件以换行符作为记录分隔符,但每隔几千条记录,就会在列中添加以\开头的换行符转义序列

这是一个示例数据集

a   b   c
a   b   c
a   b   c
a   b   c
a   b   c
a   b   c\
\   \   \
\   \   d
a   b   c
a   b   c
每当换行符前面有\时,这意味着这不是记录的结尾,并将继续,直到它到达一个不带\的换行符为止。我使用负查找断言将转义字符串作为一条记录,其余行作为一条记录

a   b   c\
\   \   \
\   \   d
这是我的密码

import org.apache.hadoop.io.LongWritable
import org.apache.hadoop.io.Text
import org.apache.hadoop.conf.Configuration
import org.apache.hadoop.mapreduce.lib.input.TextInputFormat

val LINE_DELIMITER = "(?<!\\\\)\n"

@transient val conf = new Configuration
conf.set("textinputformat.record.delimiter", LINE_DELIMITER)
val raw_file = sc.newAPIHadoopFile(path, classOf[TextInputFormat], classOf[LongWritable], classOf[Text], conf).map(_._2.toString)
如果我把这个字符串和上面定义的行分隔符分开,我会得到一个由8个字符串组成的数组。所以正则表达式本身似乎没有问题。实际的数据集有500多列,每个列有4-5G文件,所以不能使用wholeTextFiles和以后使用split


在split函数中应用regex的方式与在newapiHadoop文件中读取数据的方式有区别吗?我应该使用不同的正则表达式吗?或者使用其他机制来实现这一点?

总结我在研究这一问题时的发现。Hadoop的TextInputFormat或大多数输入格式一次处理一行。此外,它将分隔符用作字符/字符串,而不是正则表达式

解决这个问题的一种方法是构建一个自定义正则表达式InputFormat。本博客更详细地介绍了如何做到这一点

处理具有这些转义序列的少数行的另一种方法是在一个单独的RDD中过滤掉这些行,将其减少为一个字符串,并将其拆分以生成一个新的RDD,该RDD可以合并回来。这是一种黑客手段,但不是问题的真正解决方案。我们欢迎更好的解决方案

scala> raw_file.collect
res12: Array[String] = 
Array(a b   c
a   b   c
a   b   c
a   b   c
a   b   c
a   b   c\
\   \   \
\   \   d
a   b   c
a   b   c)