ClickHouse中包含模式列表元素的文本映射替换方法
ClickHouse 多子串匹配替换实现
针对非完全匹配的多规则字符串替换需求,不需要用indexOf做全值匹配,根据你使用的ClickHouse版本选对应写法即可,两种方案都支持「只要文本包含模式子串就替换为对应值、未匹配内容原样保留」的逻辑。
方案1:全版本兼容写法(无版本限制)
用arrayFold逐次遍历模式列表完成替换,所有ClickHouse版本都支持:
WITH -- 替换为你实际的匹配模式列表 ['is the', 'this is a exact mach'] AS patterns, -- 替换为你实际的对应替换值列表,注意和patterns长度、顺序一一对应 ['contains', 'replaced text exact match'] AS replacements SELECT title, arrayFold( (current_text, pattern_idx) -> replaceAll(current_text, patterns[pattern_idx], replacements[pattern_idx]), arrayEnumerate(patterns), title ) AS replaced_title FROM your_test_table -- 替换为你的实际表名
逻辑说明:
arrayEnumerate(patterns)生成和模式列表等长的序号数组,保证匹配规则和替换值下标对齐- 以原始
title为初始值,按顺序遍历所有匹配规则,每一轮把当前文本中命中的模式子串替换为对应值,遍历完成后输出最终结果 - 基于普通字符串字面量匹配,不会解析正则特殊字符,子串存在即替换,完全覆盖部分包含、全值匹配两种场景
对应测试用例执行结果:
- 输入:
this text is the second word→ 输出:this text contains second word - 输入:
this is a exact mach→ 输出:replaced text exact match
注意事项:如果多个匹配模式存在互相包含的情况,把更长的模式放在数组靠前位置,避免短模式先替换破坏长模式的匹配逻辑。
方案2:高版本简便写法(ClickHouse 21.10+)
如果你的集群版本在21.10及以上,直接用内置的multiReplaceAll函数即可,性能更优(单次扫描文本完成所有替换,无多轮替换的顺序冲突问题),写法更简洁:
WITH -- 按(匹配模式, 替换值)的格式写配对列表 [('is the', 'contains'), ('this is a exact mach', 'replaced text exact match')] AS replace_rules SELECT title, multiReplaceAll(title, replace_rules) AS replaced_title FROM your_test_table
如果需要按正则规则做匹配(比如忽略大小写、匹配可变格式片段),把上述方案里的replaceAll/multiReplaceAll替换为regexpReplace/multiRegexpReplace即可,逻辑完全一致。
内容的提问来源于stack exchange,提问作者lino
相关产品推荐
相关产品推荐

