Apache spark Spark Scala-拆分字符串语法问题
我正在尝试使用SparkSQL和Scala拆分DataFrame列中的字符串, 分裂条件对两者的作用方式似乎有所不同 使用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
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