如何在PySpark中对数组元素应用正则表达式校验?
问题描述
我有一段用于验证嵌套JSON字段的PySpark代码:
"CASE WHEN array_contains(transform(RECORDS_003.DATA.TOTAL_CHARGE, x -> trim(x)), '') OR exists(RECORDS_003.DATA.TOTAL_CHARGE, x -> x IS NULL) THEN 'TOTAL_CHARGE is missing' ELSE NULL END",
其中DATA是JSON数组,每个JSON对象包含TOTAL_CHARGE字段,这段验证代码运行正常。
现在需要对数组中每个元素校验金额正则表达式(^[-+]?[0-9]*\.?[0-9]+$),若存在不匹配元素则返回错误提示。尝试以下代码后出现类型不匹配报错:
"CASE WHEN array_contains(RECORDS_003.DATA.TOTAL_CHARGE, regexp_extract(RECORDS_003.DATA.TOTAL_CHARGE, r'^[-+]?[0-9]*\.?[0-9]+$', 0)) THEN 'TOTAL_CHARGE is invalid' ELSE NULL END"
报错信息:
AnalysisException: cannot resolve 'regexp_extract(df_view.RECORDS_003.`DATA`.`TOTAL_CHARGE`, '^[-+]?[0-9]*\\.?[0-9]+$', 0)' due to data type mismatch: argument 1 requires string type, however, 'df_view.RECORDS_003.`DATA`.`TOTAL_CHARGE`' is of array<string> type.; line 1 pos 56;
请问如何实现对数组中每个元素的正则表达式校验?
解决方案
报错根源是regexp_extract仅支持单个字符串输入,而你传入的是array<string>类型的数组字段,导致类型不兼容。要实现数组元素的批量正则校验,可通过以下两种方式处理:
方法1:用exists直接判断不匹配元素
"CASE WHEN exists(RECORDS_003.DATA.TOTAL_CHARGE, x -> x IS NOT NULL AND NOT regexp_like(x, r'^[-+]?[0-9]*\\.?[0-9]+$')) THEN 'TOTAL_CHARGE is invalid' ELSE NULL END"
- 逻辑:
exists遍历数组每个元素x,只要存在非空且不匹配正则的元素,就返回错误提示。
方法2:transform标记状态后用array_contains判断
"CASE WHEN array_contains(transform(RECORDS_003.DATA.TOTAL_CHARGE, x -> IF(x IS NULL OR NOT regexp_like(x, r'^[-+]?[0-9]*\\.?[0-9]+$'), 'invalid', 'valid')), 'invalid') THEN 'TOTAL_CHARGE is invalid' ELSE NULL END"
- 逻辑:先用
transform将每个元素转换为'invalid'(不匹配/为空)或'valid'(匹配),再通过array_contains检查是否存在异常状态元素。
合并原有校验逻辑
如果需要同时校验字段缺失和格式错误,可将两个条件整合:
"CASE WHEN array_contains(transform(RECORDS_003.DATA.TOTAL_CHARGE, x -> trim(x)), '') OR exists(RECORDS_003.DATA.TOTAL_CHARGE, x -> x IS NULL) THEN 'TOTAL_CHARGE is missing' WHEN exists(RECORDS_003.DATA.TOTAL_CHARGE, x -> x IS NOT NULL AND NOT regexp_like(x, r'^[-+]?[0-9]*\\.?[0-9]+$')) THEN 'TOTAL_CHARGE is invalid' ELSE NULL END"
内容的提问来源于stack exchange,提问作者Suraj Pandey
相关产品推荐
相关产品推荐

