Когда вы используете шаблоны регулярных выражений в spark-sql с двойными кавычками spark.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, шаблон сначала преобразуется в строку, а затем снова передается как функция string в split (),
Поэтому вам нужно получить \\.
перед тем, как использовать его в spark-sql
Способ получить это добавить еще 2 \
scala> "\\."
res12: String = \.
scala> "\\\\."
res13: String = \\.
scala>
Если вы просто передадите "\\."
в spark-sql, сначала он преобразуется в \.
, а затем в ".", Который в контексте регулярного выражения становится (.) "Любым" символом
то есть разделить на любой символ, и так как каждый символ находится рядом друг с другом, вы получите массив пустой строки.
Длина строки "12.1" равна четырем, и она также соответствует конечной границе "$" строки .. так что до разделения (val, '\.') [4] вы получите
пустой строки. Когда вы выполните команду split (val, '\.,') [5], вы получите null
Чтобы проверить это, вы можете передать ту же строку разделителя "\\."
в функцию regex_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>