如何使用PySpark正则正确拆分含字面量竖线的竖线分隔数据?
解决PySpark拆分含内嵌竖线的JSON字段问题
你的核心问题是普通竖线拆分无法区分字段分隔符和JSON内部的竖线,导致第三个字段的JSON被拆碎,字段错位。以下是针对大数据量场景的高效解决方案:
方案:使用正则分组精准提取各字段
利用正则表达式的分组功能,精准匹配每个字段的边界:
- 前两个字段:匹配到第一个
|和第二个|之间的内容 - 第三个字段:匹配从第一个
{到最后一个}的完整JSON(忽略内部的|) - 最后两个字段:匹配JSON结束后的
|分隔内容
完整代码实现
from pyspark.sql.functions import regexp_extract, col # 读取原始表 df = spark.sql("select value from my_table") # 定义正则表达式,分组提取5个字段 # 分组说明: # 1. ([^|]+):匹配第一个|前的所有非|字符(field1) # 2. ([^|]+):匹配第二个|前的所有非|字符(field2) # 3. (\{.*\}):匹配从{开始到}结束的所有内容(完整JSON,field3) # 4. ([^|]+):匹配JSON后的第一个|到下一个|的内容(field4) # 5. ([^|]+):匹配最后一个|后的内容(field5) pattern = r"^([^|]+)\|([^|]+)\|(\{.*\})\|([^|]+)\|([^|]+)$" df_out = df.withColumn("field1", regexp_extract(col("value"), pattern, 1)) \ .withColumn("field2", regexp_extract(col("value"), pattern, 2)) \ .withColumn("field3", regexp_extract(col("value"), pattern, 3)) \ .withColumn("field4", regexp_extract(col("value"), pattern, 4)) \ .withColumn("field5", regexp_extract(col("value"), pattern, 5)) # 选择结果字段并展示 new_table = df_out.select("field1", "field2", "field3", "field4", "field5") new_table.display()
关键说明
- 正则中的
\{.*\}使用贪婪匹配,确保捕获从第一个{到最后一个}的完整JSON,不会提前终止 - 前两个和后两个字段用
[^|]+匹配,确保只捕获字段分隔符之间的内容,不会误吞内部字符 - 这个方法在大数据量下依然高效,因为Spark的正则函数是分布式执行的,不会有性能瓶颈
额外优化:解析JSON字段(可选)
如果需要进一步解析第三个字段的JSON内容,可以用from_json函数:
from pyspark.sql.functions import from_json from pyspark.sql.types import StructType, StructField, StringType, ArrayType # 定义JSON结构的Schema menu_schema = StructType([ StructField("menu", StructType([ StructField("id", StringType()), StructField("menuitem", ArrayType(StructType([ StructField("value", StringType()), StructField("onclick", StringType()) ]))) ])) ]) # 解析JSON为结构化数据 df_with_json = df_out.withColumn("menu_data", from_json(col("field3"), menu_schema)) df_with_json.display()
内容的提问来源于stack exchange,提问作者CodeForFood
相关产品推荐
相关产品推荐

