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 |
+--------------+