Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/azure/11.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
Apache spark Spark Scala-拆分字符串语法问题_Apache Spark_Apache Spark Sql - Fatal编程技术网

Apache spark Spark Scala-拆分字符串语法问题

Apache spark Spark Scala-拆分字符串语法问题,apache-spark,apache-spark-sql,Apache Spark,Apache Spark Sql,我正在尝试使用SparkSQL和Scala拆分DataFrame列中的字符串, 分裂条件对两者的作用方式似乎有所不同 使用Scala 这很有效- val seq = Seq("12.1") val df = seq.toDF("val") Scala代码-> val seq = Seq("12.1") val df = seq.toDF("val") val afterSplit = df2.withColumn("FirstPart", split($"val", "\\.")).sele

我正在尝试使用SparkSQL和Scala拆分DataFrame列中的字符串, 分裂条件对两者的作用方式似乎有所不同

使用Scala

这很有效-

val seq = Seq("12.1")
val df = seq.toDF("val")
Scala代码->

val seq = Seq("12.1")
val df = seq.toDF("val")

val afterSplit = df2.withColumn("FirstPart", split($"val", "\\.")).select($"FirstPart".getItem(0).as("PartOne"))
afterSplit.show(false)
然而,在Spark SQL中,当我使用它时,firstParkSQL显示为空白

df.registerTempTable("temp")
val s1 = sqlContext.sql("select split(val, '\\.')[0] as firstPartSQL from temp")
相反,当我使用这个(单独的条件表示为[.]而不是\)时。 期望值显示出来

val s1 = sqlContext.sql("select split(val, '[.]')[0] as firstPartSQL from temp")

>为什么会发生这种情况?< /P> < P>当您在Sql SQL中使用ReXEX模式时,使用双引号<代码> Skp.sql(“…”)<代码>,它被认为是另一个字符串中的字符串,因此发生了两件事。

scala> val df = Seq("12.1").toDF("val")
df: org.apache.spark.sql.DataFrame = [val: string]

scala> df.withColumn("FirstPart", split($"val", "\\.")).select($"FirstPart".getItem(0).as("PartOne")).show
+-------+
|PartOne|
+-------+
|     12|
+-------+


scala> df.createOrReplaceTempView("temp")
使用df(),split的正则表达式字符串将直接传递给split字符串,因此只需转义反斜杠(\)

但对于spark sql,模式首先转换为字符串,然后再作为字符串传递给split()函数, 因此,在spark sql中使用之前,需要先获取
\\.

获得该值的方法是再添加2个
\

scala> "\\."
res12: String = \.

scala> "\\\\."
res13: String = \\.

scala>
如果您只是在spark sql中传递
“\\.”
,首先将其转换为
\.
,然后转换为“.”,它在正则表达式上下文中成为(.)“任意”字符 i、 e在任何字符上拆分,由于每个字符彼此相邻,因此会得到一个空字符串数组。 字符串“12.1”的长度为4,并且它也与字符串的最终边界“$”匹配。因此,在split(val,“\”)[4]之前,您将得到 空字符串。当您发出split(val,“\,”)[5]时,您将得到
null

要验证这一点,您可以将相同的分隔符字符串
“\\.”
传递给regex\u replace()函数,并查看发生了什么

scala> spark.sql("select split(val, '\\.')[0] as firstPartSQL, regexp_replace(val,'\\.','9') as reg_ex from temp").show
+------------+------+
|firstPartSQL|reg_ex|
+------------+------+
|            |  9999|
+------------+------+

scala> spark.sql("select split(val, '\\\\.')[0] as firstPartSQL, regexp_replace(val,'\\\\.','9') as reg_ex from temp").show
+------------+------+
|firstPartSQL|reg_ex|
+------------+------+
|          12|  1291|
+------------+------+


scala>
如果您仍然希望在df和sql之间使用相同的模式,那么使用原始字符串,即三重引号

scala> raw"\\."
res23: String = \\.

scala>

scala> spark.sql("""select split(val, '\\.')[0] as firstPartSQL, regexp_replace(val,'\\.','9') as reg_ex from temp""").show
+------------+------+
|firstPartSQL|reg_ex|
+------------+------+
|          12|  1291|
+------------+------+


scala> spark.sql("""select split(val, "\\.")[0] as firstPartSQL, regexp_replace(val,"\\.",'9') as reg_ex from temp""").show
+------------+------+
|firstPartSQL|reg_ex|
+------------+------+
|          12|  1291|
+------------+------+


scala>

这是因为SQL需要额外的转义,即从temp中选择split(val,'\\\.')[0]作为firstPartSQL