匹配带/不带引号的动态JSON正则表达式需求
问题分析
首先看你的输入是一段不规范的JSON片段,键都用双引号包裹,值分三种情况:带双引号的字符串、数字、null(无引号)。你需要用正则提取键值对,同时还要适配Talend处理动态Schema的场景,不能用常规JSON解析器。
正则方案
这里给你一个能覆盖所有情况的正则表达式,支持全局匹配所有键值对:
"([^"]+)"\s*:\s*(?:"([^"\\]*(?:\\.[^"\\]*)*)"|([^\s}]+))
正则解释
"([^"]+)":捕获双引号包裹的键名,[^"]+匹配非引号的所有字符(确保键的双引号内内容被完整提取)\s*:\s*:匹配冒号,同时兼容冒号前后的任意空格(?:"([^"\\]*(?:\\.[^"\\]*)*)"|([^\s}]+)):分支匹配两种值类型- 第一个分支:
"([^"\\]*(?:\\.[^"\\]*)*)",捕获双引号包裹的字符串值,支持处理转义引号(比如\")这种边缘情况 - 第二个分支:
([^\s}]+),捕获不带引号的值(数字、null等),用[^\s}]+确保不会匹配到后面的分隔空格或}符号
- 第一个分支:
Talend 具体操作步骤
- 读取原始字符串:用
tFileInputRaw或tRowGenerator获取你的不规范JSON片段 - 提取正则分组:添加
tExtractRegexFields组件,勾选「Global match」(全局匹配所有键值对),将上面的正则填入,然后添加三个输出列:key(String类型,对应正则分组1)value_quoted(String类型,对应正则分组2)value_unquoted(String类型,对应正则分组3)
- 合并值列:用
tMap组件,添加一个计算列value,表达式写:
这个表达式会自动判断值是来自带引号的分组还是无引号的分组value_quoted != null ? value_quoted : value_unquoted - 输出结果:将
tMap的key和value列输出,就能得到你需要的Key|Value格式
更优替代方案
正则虽然能解决问题,但遇到复杂的转义字符或更不规范的JSON时容易出错。如果你的Talend支持Groovy组件,推荐用tGroovy写脚本处理,容错性更强:
// 读取输入的原始字符串 def rawJson = input_row.rawString; // 先修复不规范的JSON格式:把空格分隔的键值对改成逗号分隔,补全外层大括号 def fixedJson = rawJson.replaceAll(/(?<=[}\]])\s+/, ",").replaceAll(/\s+/, " "); fixedJson = "{ " + fixedJson + " }"; // 用Groovy的JsonSlurper解析(容错性强,能处理大部分不规范JSON) def jsonObj = new groovy.json.JsonSlurper().parseText(fixedJson); // 遍历所有键值对并输出 jsonObj.each { entry -> output_row.key = entry.key; output_row.value = entry.value != null ? entry.value.toString() : "null"; output(); }
这种方法不需要依赖正则的精确匹配,能更好地处理动态Schema的场景,即使后续新增字段也不需要修改正则。
内容的提问来源于stack exchange,提问作者prakul
相关产品推荐
相关产品推荐

