在Hadoop中使用正则表达式提取字符串指定内容的问题
问题分析与解决方案
目标字符串:BCRIS-QUEBEC.C67950210QC.5147650116.O5000977510.RD02.0026.00001.DistributionPair.O,需提取DistributionPair前第3个点分隔段(即示例中的RD02)到Dist_Cu_Cable列。
原代码问题点
- 正则匹配逻辑偏差:原正则的贪婪匹配可能捕获到非目标位置的字段,无法精准定位到
DistributionPair前的目标段。 - 代码冗余:内层
CASE判断多余,外层已过滤包含distributionpair的记录。 - 工具选择不当:用
REGEXP_REPLACE实现提取不如REGEXP_EXTRACT直接高效。
解决方案一:Split+数组定位(直观易维护)
通过分割字符串为数组,定位DistributionPair的位置后直接取对应元素:
MAX( CASE WHEN lower(associatedwoi_id) LIKE '%distributionpair%' THEN CASE WHEN size(arr) >= 8 THEN arr[dp_idx - 3] END END ) AS Dist_Cu_Cable FROM ( SELECT associatedwoi_id, split(associatedwoi_id, '\\.') AS arr, -- 将DistributionPair的位置转为0-based索引 array_position(split(lower(associatedwoi_id), '\\.'), 'distributionpair') - 1 AS dp_idx FROM your_table ) t
split(associatedwoi_id, '\\.'):按点分割字符串为数组。array_position(...):找到小写后数组中distributionpair的1-based位置,转换为0-based索引。arr[dp_idx - 3]:取DistributionPair前第3个元素(示例中dp_idx=7,7-3=4对应RD02)。
解决方案二:REGEXP_EXTRACT(简洁高效)
直接用正则提取目标字段,无需复杂嵌套:
MAX( CASE WHEN lower(associatedwoi_id) LIKE '%distributionpair%' THEN REGEXP_EXTRACT(associatedwoi_id, '(?i)\\.([^.]+)\\.[^.]+\\.[^.]+\\.DistributionPair', 1) END ) AS Dist_Cu_Cable
(?i):开启不区分大小写匹配,兼容distributionpair的大小写变体。\\.([^.]+)\\.[^.]+\\.[^.]+\\.DistributionPair:匹配.[目标字段].[任意字段].[任意字段].DistributionPair结构,捕获组1即为目标字段。REGEXP_EXTRACT(..., 1):提取第一个捕获组的内容。
内容的提问来源于stack exchange,提问作者user21294168
相关产品推荐
相关产品推荐

