如何在PySpark的Spark SQL中用regexp_replace替换|为^
问题分析
你的问题核心在于双重转义冲突:
- Python字符串会先解析转义符,你写的
\\|经过Python处理后,实际传给Spark SQL的是\| - 而Spark SQL的正则表达式中,
|是特殊元字符(表示“或”),但\|并没有正确转义|,反而被识别为匹配空字符的模式,最终导致每个字符前后都被替换成^
解决方案
提供三种可靠的解决方式,按需选择:
方式1:使用四重反斜杠转义
在Python字符串中,用\\\\|来表示Spark SQL所需的\|——Python会先把\\\\解析为\\,最终传入Spark的就是正确转义后的|:
dd=spark.sql("""select 'Q1|31-JUL-18|Clean, Q3|31-JAN-19|Clean, Q9' desc, regexp_replace('Q1|31-JUL-18|Clean, Q3|31-JAN-19|Clean, Q9','\\\\|','\\^') new_desc""") dd.show(truncate=False)
方式2:使用Python原始字符串(推荐)
在SQL字符串前加r前缀,让Python跳过转义符解析,直接把正则表达式原样传给Spark SQL:
dd=spark.sql(r"""select 'Q1|31-JUL-18|Clean, Q3|31-JAN-19|Clean, Q9' desc, regexp_replace('Q1|31-JUL-18|Clean, Q3|31-JAN-19|Clean, Q9','\|','^') new_desc""") dd.show(truncate=False)
注:替换字符^无需转义,它在正则替换字符串中不属于特殊字符。
方式3:用translate函数替代正则(适合简单字符替换)
如果只是替换单个普通字符,不需要正则的复杂功能,可以用translate函数彻底规避转义问题:
dd=spark.sql(r"""select 'Q1|31-JUL-18|Clean, Q3|31-JAN-19|Clean, Q9' desc, translate('Q1|31-JUL-18|Clean, Q3|31-JAN-19|Clean, Q9','|','^') new_desc""") dd.show(truncate=False)
验证结果
以上三种方式都会输出你期望的结果:
+------------------------------------------+-------------------------------------------------------------------------------------+ |desc |new_desc | +------------------------------------------+-------------------------------------------------------------------------------------+ |Q1|31-JUL-18|Clean, Q3|31-JAN-19|Clean, Q9|Q1^31-JUL-18^Clean, Q3^31-JAN-19^Clean, Q9| +------------------------------------------+-------------------------------------------------------------------------------------+
内容的提问来源于stack exchange,提问作者Liu Yu
相关产品推荐
相关产品推荐

