全部產品
Search
文件中心

MaxCompute:UDF樣本:擷取字串(含分隔字元)Value

更新時間:Jun 19, 2024

本文為您介紹如何分別通過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 |
+--------------+