PySpark中使用regexp_replace移除开头+号及前导零的正则方法
问题解答
完全可以通过regexp_replace搭配正则实现该需求,你原有代码无法得到正确结果是因为正则的语法和匹配逻辑都存在错误。
原有正则的问题
你编写的正则^([0-9]|[1-9][0-9])$+存在两处核心错误:
- 锚点使用错误:
$是匹配字符串结尾位置的锚点,放在量词+前不符合正则语法规则 - 匹配逻辑偏离需求:该正则实际只能匹配长度为1位的纯数字,或者长度为2位、首位为1-9的纯数字,完全无法命中开头的
+号和数字前导零,自然无法得到预期结果
正确实现代码
针对你给出的输入场景(输入格式为带+前缀、整数部分含前导零的有效小数,如+00000000995510.32),使用以下代码即可得到995510.32的预期输出:
from pyspark.sql.functions import regexp_replace, col df = df.withColumn("vl_fat", regexp_replace(col("vl_fat"), r"^\+?0*(?=[1-9])", ""))
正则逻辑说明
^:匹配字符串的开头位置,确保只处理开头的目标字符\+?:匹配开头可选的+号(?表示该字符出现0次或1次,兼容不带+的前导零字符串)0*:匹配连续任意个数字0(?=[1-9]):正向预查规则,要求前面匹配到的所有0后面必须跟着1-9的非零数字,保证只会删除第一个非零数字之前的+和前导零,不会损伤有效数字、小数部分的内容
边界场景兼容
如果你的数据中还存在整数部分全为0的小数场景(例如输入为+0000.32,预期输出为0.32),可以将代码调整为捕获组加条件判断的写法,兼容全场景:
注意:使用该段代码时,需要额外从
pyspark.sql.functions导入when, concat, lit函数。
df = df.withColumn( "vl_fat", regexp_replace( col("vl_fat"), r"^\+?0*([1-9]\d*(?:\.\d+)?)$|^\+?0*(\.\d+)$|^\+?0+$", "$1" ) ).withColumn( "vl_fat", when(col("vl_fat").startswith("."), concat(lit("0"), col("vl_fat"))) .when(col("vl_fat") == "", lit("0")) .otherwise(col("vl_fat")) )
内容的提问来源于stack exchange,提问作者Carlos Eduardo Bilar Rodrigues
相关产品推荐
相关产品推荐

