Python版Apache Beam使用Replace函数替换横线失效问题排查
问题根因
你代码失效的核心原因有两个:
- 对
ReadFromText返回的元素结构理解错误:该接口读取CSV时,每一条输出是未做任何分割的整行字符串,不是按逗号拆分后的字段列表。
你之前测试record[0][0] == "3"能命中,纯粹是因为整行字符串的第一个字符恰好是'3',属于误打误撞;但你写record[12][0] == "-"时,取的是整行字符串下标为12的字符——对照你的示例行,下标12的位置是APPLE里的第二个字符'P',永远不可能等于'-',所有行都被Filter过滤掉了,结果文件自然是空的。 - 全局正则替换逻辑有副作用:就算Filter逻辑正常,直接用
Regex.replace_all("-", 目标值)会把字符串里所有的'-'都替换掉,包括日期字段2022-04里的连接横杠,不符合你只替换空值标记'-'的需求。
正确实现方案
优先选择按字段拆分处理的逻辑,不会误改非空值字段里的横杠,容错性更高:
import apache_beam as beam def replace_empty_dash(line: str) -> str: # 按逗号拆分CSV字段 fields = line.split(',') # 仅替换值完全等于'-'的字段为0 processed = [ '0' if field.strip() == '-' else field for field in fields ] # 重新拼接为CSV行 return ','.join(processed) p = beam.Pipeline() ( p | beam.io.ReadFromText('AUD-1.csv', skip_header_lines=1) | beam.Map(replace_empty_dash) | beam.io.WriteToText('replace_result.csv') ) p.run()
处理你给出的示例行时,输出结果为:3019337728,APPLE IPHONE,2022-04,Preroll,DUBAI BRANCH,Saudi Arabia,Gender=Male,CPM,3,0,75000,0,0
日期字段里的'-'会被完整保留,只有作为单独空值的'-'被替换为0。
如果你坚持用正则方式实现,需要写匹配字段边界的正则,避免误替换:
# 仅替换前后为逗号/行首/行尾的独立'-' | beam.Regex.replace_all(r"(?<=,|^)-(?=,|$)", "0")
这种写法对格式不规范的CSV兼容性差,不推荐在生产场景使用。
内容的提问来源于stack exchange,提问作者Lakshmi_N
相关产品推荐
相关产品推荐

