首先,声明使用引擎是spark,经实验regexp_replace在spark和presto中效果不同。仅说明在spark中效果。
场景:从后端获取的数据是JSON格式,需要提取其中的字段,构建数据模型。一个字典格式中包含一个或多个键值对。形如:
[{"businessId":"JD","promotionRate":90},{"businessId":"VSP","promotionRate":0},{"businessId":"FL","promotionRate":10}]
目标:需要拆分成下表所示的形式
businessId | promotionRate |
JD | 90 |
VSP | 0 |
FL | 10 |
具体操作:
explode( split(regexp_replace( regexp_replace( business_promote, '\\[|\\]', '' ) ,'\\}\\,\\{' , '\\}\\|\\{') , '\\|' ) )
首先,使用 regexp_replace() 函数,对JSON格式指定字符删除。
使用方法:
regexp_replace(source, pattern, replace_string, occurrence)
- source: string类型,要替换的原始字符串。
- pattern: string类型常量,要匹配的正则模式,pattern为空串时抛异常。
- replace_string:string,将匹配的pattern替换成的字符串。
- occurrence: bigint类型常量,必须大于等于0,大于0:表示将第几次匹配替换成replace_string,等于0:表示替换掉所有的匹配子串。其它类型或小于0抛异常。
其中涉及正则表达式的使用,正则符号释义:
双层函数嵌套
regexp_replace( business_promote, '\\[|\\]', '' ) ,第一层:把前后的[]替换为空,就是去除前后的中括号,//表示转义。
所谓特殊字符,就是一些有特殊含义的字符,如上面说的 runoo*b 中的 *,简单的说就是表示任何字符串的意思。如果要查找字符串中的 * 符号,则需要对 * 进行转义,即在其前加一个 \,runo\*ob 匹配字符串 runo*ob。
许多元字符要求在试图匹配它们时特别对待。若要匹配这些特殊字符,必须首先使字符"转义",即,将反斜杠字符\ 放在它们前面。下表列出了正则表达式中的特殊字符。
这个函数中使用了两次regexp_replace函数,主要是为了替换文本中的特定模式。让我来一步步解释:
1. 第一个regexp_replace函数是这样的:regexp_replace(business_promote, '\\[|\\]',''),它的作用是将business_promote中的所有'['和']'字符替换为空字符串。这里的'\\[|\\]'是一个正则表达式,表示匹配'['或者']'。
2. 第二个regexp_replace函数是这样的:regexp_replace(result_of_previous_step,'\\}\\,\\{','\\}\\|\\{'),它的作用是将上一步的结果中的所有'},{'替换为'}|{'。同样,'\\}\\,\\{'是一个正则表达式,表示匹配'},{'。
3. 最后一个\\|''是将上一步的结果中的所有'|'替换为空字符串。
所以最终的效果是对business_promote中的特定字符进行了多次替换操作,最终得到了我们需要的结果。
b. 然后是split函数:
- split函数根据'|'这个分隔符,将经过内层regexp_replace处理后的字符串拆分成数组。
c. 最后是explode函数:
- explode函数将split得到的数组中的每个元素拆分为单独的行,生成最终的结果。
--------------------------------------------------------------------
第一次写博客感觉有点啰嗦,希望能坚持下来!