如何用正则表达式为PySpark DataFrame列添加指定双引号?
PySpark正则表达式处理字符串字段问题
问题场景
原始字符串数据:
tuff,1,2,3,bp123,5,6,7,jatin gupta ,ext,20021988
需求:在第8个逗号后(无引号时)添加左双引号,在数字20021988前添加右双引号,期望输出:
tuff,1,2,3,bp123,5,6,7,"jatin gupta ,ext",20021988
用户尝试的代码
data = [("TUFF,2,3,BP4,5,6,7,JATIN GUPTA, EXT, 20021988",)] columns = ["input_string"] # 创建DataFrame df = spark.createDataFrame(data, columns) # 使用正则表达式在第7个逗号后添加引号,在8位数字前添加右引号 df = df.withColumn("output_string", regexp_replace(col("input_string"), r"((?:[^,]*,){7})([^,]*,[^,]*),([^,]*)", r'\1"\2", \3'))
问题分析
原正则表达式存在两个核心问题:
- 匹配逻辑不够精准:
([^,]*,[^,]*)对目标段的匹配范围定义模糊,没有精准锁定到结尾的8位数字前 - 未处理重复添加引号的情况:没有判断目标段是否已有引号,会导致重复包裹
正确解决方案
调整正则表达式,精准定位目标片段并避免重复添加引号:
from pyspark.sql.functions import regexp_replace, col data = [ ("tuff,1,2,3,bp123,5,6,7,jatin gupta ,ext,20021988",), ("tuff,1,2,3,bp123,5,6,7,""jatin gupta ,ext"",20021988",) # 模拟已有引号的场景 ] columns = ["input_string"] df = spark.createDataFrame(data, columns) # 正则表达式逻辑: # 1. 匹配前7个逗号分隔的完整内容 # 2. 负向预查确保目标段无引号,再捕获需要包裹的内容 # 3. 精准匹配结尾的8位数字前的分隔符 df = df.withColumn( "output_string", regexp_replace( col("input_string"), r"((?:[^,]*,){7})(?!")([^,]*,[^,]+),(\d{8})$", r'\1"\2",\3' ) ) # 查看结果 df.show(truncate=False)
正则表达式说明
((?:[^,]*,){7}):匹配前7个逗号分隔的所有内容(例如tuff,1,2,3,bp123,5,6,7,)(?!"):负向预查,确保目标段开头没有双引号,避免重复包裹([^,]*,[^,]+):捕获第8和第9个逗号之间的目标内容(即jatin gupta ,ext),(\d{8})$:精准匹配结尾的逗号加8位数字,锁定右引号的插入位置
执行后输出结果:
+-----------------------------------------------------+-------------------------------------------------------+ |input_string |output_string | +-----------------------------------------------------+-------------------------------------------------------+ |tuff,1,2,3,bp123,5,6,7,jatin gupta ,ext,20021988 |tuff,1,2,3,bp123,5,6,7,"jatin gupta ,ext",20021988 | |tuff,1,2,3,bp123,5,6,7,"jatin gupta ,ext",20021988 |tuff,1,2,3,bp123,5,6,7,"jatin gupta ,ext",20021988 | +-----------------------------------------------------+-------------------------------------------------------+
内容的提问来源于stack exchange,提问作者Gourav Joshi
相关产品推荐
相关产品推荐

