UDF示例:获取字符串(含分隔符)Value

UDF示例:获取字符串(含分隔符)Value

本文为您介绍如何分别通过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 |
+--------------+