本文为您介绍如何分别通过Java UDF和Python UDF实现获取键值对字符串中指定Key对应的Value值,其中Key或Value本身含有二级分隔符。
命令说明
本示例将注册一个名称为UDF_EXTRACT_KEY_VALUE_WITH_SPLIT的自定义函数,下面对命令格式和入参进行说明。
string UDF_EXTRACT_KEY_VALUE_WITH_SPLIT(string <s>, string <split1>, string <split2>, string <keyname>)
函数功能:在键值对字符串s中使用split1分割出键值对后,再根据split2分割键值对获得键和值,最后返回键keyname对应的值。与获取键值对字符串中指定Key的Value示例主要的不同在于,该UDF适用于Key或者Value本身含有二级分隔符的情况。
参数说明:
s:源字符串,STRING类型,必填。
split1:通过split1分割出键值对,STRING类型,必填。
split2:对分割出来的键值对使用split2进行分割,STRING类型,必填。
keyname:待获取值所对应的键名称,STRING类型,必填。
开发和使用步骤
1. 代码开发
Java UDF 代码示例
package com.aliyun.rewrite; //package名称,可以根据您的情况定义。
import com.aliyun.odps.udf.UDF;
public class ExtractKeyValueWithSplit extends UDF{
/**
* 使用split1分割出键值对后,再根据split2分割键值对
* @param str 源字符串
* @param split1 分割出键值对的标识
* @param split2 分割出key value的标识
* @param keyname 目标key名称
* @return 目标value
*/
public String evaluate(String str, String split1, String split2, String keyname) {
if(str==null || split1==null || split2==null || keyname==null){
return null;
}
try {
// 将keyname和二级分割符组合
String keySplit = keyname + split2;
// 遍历字符串,先用split1进行键值对分割。
for(String subStr: str.split(split1)){
// 匹配key+split2,获取字符串剩余的value值
if (subStr.startsWith(keySplit)){
return subStr.substring(keySplit.length());
}
}
} catch (Exception e) {
return null;
}
return null;
}
}
使用Java语言编写UDF代码必须继承UDF类,本例中evaluate方法定义了四个string类型的入参和string类型的返回值,输入参数和返回值的数据类型将作为SQL语句中UDF的函数签名Signature,其他代码规范和要求请参考:UDF开发规范与通用流程(Java)。
Python3 UDF 代码示例
from odps.udf import annotate
@annotate("string,string,string,string->string")
class ExtractKeyValueWithSplit(object):
def evaluate(self, s, split1, split2, keyname):
if not s:
return None
key_split = keyname + split2
# 遍历字符串,先用split1进行键值对分割。
for subStr in s.split(split1):
# 匹配key+split2,获取字符串剩余的value值
if subStr.startswith(key_split):
return subStr[len(key_split):]
MaxCompute默认使用Python 2,可以在Session级别使用命令set odps.sql.python.version=cp37
开启Python 3。更多 Python3 UDF规范请参考:UDF开发规范与通用流程(Python3)。
Python2 UDF 代码示例
#coding:utf-8
from odps.udf import annotate
@annotate("string,string,string,string->string")
class ExtractKeyValueWithSplit(object):
def evaluate(self, s, split1, split2, keyname):
if not s:
return None
key_split = keyname + split2
# 遍历字符串,先用split1进行键值对分割。
for subStr in s.split(split1):
# 匹配key+split2,获取字符串剩余的value值
if subStr.startswith(key_split):
return subStr[len(key_split):]
当Python 2代码中出现中文字符时,运行程序会报错,必须在代码头部增加编码声明。固定声明格式为#coding:utf-8
或# -*- coding: utf-8 -*-
,二者等效。更多 Python2 UDF规范请参考:UDF开发规范与通用流程(Python2)。
2. 上传资源和注册函数
完成UDF代码开发和调试之后,将资源上传至MaxCompute并注册函数,本示例注册函数名:UDF_EXTRACT_KEY_VALUE_WITH_SPLIT。Java UDF上传资源与注册函数详情步骤请参见:打包、上传及注册,Python UDF请参见:上传及注册。
3. 使用示例
成功注册UDF后,执行以下命令,从键值对字符串中获取键为name的值,而name对应的value是包含分隔符。
set odps.sql.python.version=cp37; -- python3 UDF需要使用该命令开启python3
SELECT UDF_EXTRACT_KEY_VALUE_WITH_SPLIT('name:zhangsang:man;age:2;', ';', ':', 'name');
执行结果如下:
+--------------+
| _c0 |
+--------------+
| zhangsan:man |
+--------------+