2016-10-20 2 views
1

Недавно я пытался ответить на вопрос question, когда понял, что не знаю, как использовать обратную ссылку в регулярном выражении с помощью Spark DataFrames.Back-reference in Spark DataFrame `regexp_replace`

Например, с СЭД, я мог бы сделать

> echo 'a1 
b22 
333' | sed "s/\([0-9][0-9]*\)/;\1/"                         

a;1 
b;22 
;333 

Но с искровым DataFrames я не могу:

val df = List("a1","b22","333").toDF("str") 
df.show 

+---+ 
|str| 
+---+ 
| a1| 
|b22| 
|333| 
+---+ 

val res = df .withColumn("repBackRef",regexp_replace('str,"(\\d+)$",";\\1")) 
res.show 

+---+-----------+ 
|str|repBackRef| 
+---+----------+ 
| a1|  a;1| 
|b22|  b;1| 
|333|  ;1| 
+---+----------+ 

Просто чтобы понять: я не хочу результат этот конкретный случай, я хотел бы решение, которое было бы таким общим, как обратная ссылка, например, sed.

Следует также отметить, что использование regexp_extract отсутствует, так как он ведет себя плохо, когда нет соответствия:

val res2 = df 
    .withColumn("repExtract",regexp_extract('str,"^([A-z])+?(\\d+)$",2)) 
res2.show 

Так что вы вынуждены использовать один столбец в шаблон, чтобы извлечь как я сделал в указанном answer.

Спасибо!

+1

Попробуйте использовать '$ 1 'вместо' \\ 1'. –

+0

да! Благодаря! Я искал такой тривиальный синтаксис, как это, но я не нашел его. Я соглашусь, если вы ответите. – Wilmerton

ответ

2

Вы должны использовать синтаксис $ + numeric_ID обратной ссылки:

.withColumn("repBackRef",regexp_replace('str,"(\\d+)$",";$1")) 
                 ^^