PySpark正则表达式优化:忽略双引号内逗号以准确定位子串
解决PySpark DataFrame中带引号字段的逗号计数与字符串格式化问题
问题分析
原正则无法正确计数引号内包含逗号的字段,导致第57个逗号的位置判断错误。需要先实现忽略双引号内逗号的逗号计数,再完成三个格式化需求:
- 第57个逗号后添加双引号
- 在
,\d{2},\d{4}模式前闭合双引号 - 包裹指定地址子串
解决方案
分两步处理,先处理地址子串包裹,再处理引号的添加与闭合,确保正则能正确跳过引号内的逗号。
1. 用双引号包裹地址子串
先匹配目标地址子串,直接用双引号包裹:
from pyspark.sql.functions import regexp_replace # 匹配用户指定的地址模式,替换为带双引号的形式 df = df.withColumn( "your_column_name", regexp_replace( "your_column_name", r"(Flat No \w+, Balaji Whitefield society, sus road, pune,Mh)", r"\"$1\"" ) )
如果地址子串有变体(比如大小写、空格差异),可以调整正则为更宽松的模式:
r"(Flat No \w+, .*?Balaji Whitefield society, .*?sus road, .*?pune,.*?Mh)"
2. 正确计数逗号并添加/闭合双引号
修改正则表达式,通过交替匹配双引号包裹内容和非逗号/非引号内容,实现忽略引号内逗号的计数逻辑:
Pattern = r"^((?:(?:\"[^\"]*\"|[^,\"])*,){57})(.*?)(,\d{2},\d{4}.*)$" df = df.withColumn( "your_column_name", regexp_replace( "your_column_name", Pattern, r"$1\"$2\"$3" ) )
正则说明:
(?:\"[^\"]*\"|[^,\"])*:匹配零次或多次,要么是双引号包裹的完整内容(内部逗号不被计数),要么是不含逗号和双引号的普通文本(?:...){57}:重复57次,确保正确计数到第57个引号外的逗号(.*?):非贪婪匹配第57个逗号后到,\d{2},\d{4}前的所有内容- 替换逻辑:在第57个逗号后插入
",在,\d{2},\d{4}前插入",完成引号的添加与闭合
验证场景
针对包含带逗号的引号字段(如"SAM,K,KARAN")的字符串,该正则会自动跳过引号内的逗号,准确找到第57个引号外的逗号,同时正确包裹地址子串并在指定位置添加/闭合双引号。
内容的提问来源于stack exchange,提问作者Gourav Joshi
相关产品推荐
相关产品推荐

