キーと値の文字列のキーまたは値にデリミタ文字が含まれている場合、組み込みの KEYVALUE 関数では正しく解析できません。 このような文字列から値を抽出するには、ユーザー定義関数 (UDF) の UDF_EXTRACT_KEY_VALUE_WITH_SPLIT を使用します。
このトピックでは、Java または Python で UDF を作成し、MaxCompute に登録して、SQL で呼び出すまでの手順を説明します。
手順:
関数シグネチャ
string UDF_EXTRACT_KEY_VALUE_WITH_SPLIT(string <s>, string <split1>, string <split2>, string <keyname>)
この関数は、s を split1 を使用してキーと値のペアに分割し、次に split2 を使用して各ペアをキーと値に分割し、keyname で指定されたキーの値を返します。
パラメーター (すべて STRING 型、すべて必須):
| パラメーター | 説明 |
|---|---|
s |
解析対象の文字列 |
split1 |
キーと値のペアを分割するデリミタ |
split2 |
キーと値を分割するデリミタ |
keyname |
値を取得する対象のキー |
いずれかのパラメーターが null の場合、またはキーが見つからない場合、この関数は null を返します。
前提条件
開始する前に、以下が準備できていることを確認してください。
-
UDF 開発権限を持つ MaxCompute プロジェクト
-
UDF コードを作成およびテストするための Java または Python 開発環境
1. UDF の作成
UDF 実装に使用する言語を選択します。 3 つの実装はすべて同じ結果を生成します。
Java
package com.aliyun.rewrite; // パッケージ名。ユーザー定義です。
import com.aliyun.odps.udf.UDF;
public class ExtractKeyValueWithSplit extends UDF{
/**
* split1 を使用して文字列を分割し、キーと値のペアを取得します。 次に、split2 を使用してキーと値のペアを分割し、キーと値を取得します。
* @param str ソース文字列。
* @param split1 文字列を分割してキーと値のペアを取得するために使用されるデリミタ。
* @param split2 キーと値のペアを分割してキーと値を取得するために使用されるデリミタ。
* @param keyname 値を取得するキーの名前。
* @return 返される値。
*/
public String evaluate(String str, String split1, String split2, String keyname) {
if(str==null || split1==null || split2==null || keyname==null){
return null;
}
try {
// keyname と split2 を結合します。
String keySplit = keyname + split2;
// 文字列を走査します。 split1 を使用して文字列を分割し、キーと値のペアを取得します。
for(String subStr: str.split(split1)){
// split2 を使用してキーと値のペアを分割し、キーと値を取得します。 次に、特定のキーに対応する値を取得します。
if (subStr.startsWith(keySplit)){
return subStr.substring(keySplit.length());
}
}
} catch (Exception e) {
return null;
}
return null;
}
}
Java UDF は UDF クラスを継承する必要があります。 evaluate メソッドは、SQL ステートメントで使用される関数シグネチャを定義します。このシグネチャは、4つの STRING 入力パラメーターと1つの STRING 戻り値で構成されます。 その他のコード仕様については、「Java UDF」をご参照ください。
Python 3
MaxCompute プロジェクトは、デフォルトで Python 2 を実行します。 この Python 3 UDF を使用するには、呼び出す前にセッションレベルで次のコマンドを実行します: set odps.sql.python.version=cp37。
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):
# split2 を使用してキーと値のペアを分割し、キーと値を取得します。 次に、特定のキーに対応する値を取得します。
if subStr.startswith(key_split):
return subStr[len(key_split):]
Python 3 UDF の仕様については、「Python 3 UDF」をご参照ください。
Python 2
#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):
# split2 を使用してキーと値のペアを分割し、キーと値を取得します。 次に、特定のキーに対応する値を取得します。
if subStr.startswith(key_split):
return subStr[len(key_split):]
Python 2 UDF コードに中国語文字が含まれている場合は、ファイルの先頭にエンコーディング宣言を追加してください: #coding:utf-8 または # -*- coding: utf-8 -*-。 この宣言がない場合、MaxCompute は UDF の実行時にエラーを返します。
Python 2 UDF の仕様については、「Python 2 UDF」をご参照ください。
2. リソースのアップロードと UDF の登録
UDF を作成してテストした後、コードを MaxCompute にアップロードし、UDF_EXTRACT_KEY_VALUE_WITH_SPLIT として登録します。
-
Java UDF:詳細については、「Java プログラムのパッケージ化、パッケージのアップロード、MaxCompute UDF の作成」をご参照ください。
-
Python UDF: 「Python プログラムをアップロードして MaxCompute UDF を作成する」をご参照ください。
3. UDF の使用
UDF を登録した後、SQL ステートメントで呼び出します。 次の例では、値自体にデリミタ : が含まれる文字列から、キー name の値を抽出します。
set odps.sql.python.version=cp37; -- Python 3 UDF の場合にのみ必要です。 Java または Python 2 の場合は、この行を省略してください。
SELECT UDF_EXTRACT_KEY_VALUE_WITH_SPLIT('name:zhangsang:man;age:2;', ';', ':', 'name');
この例では:
-
split1は;で、文字列をname:zhangsang:manとage:2のペアに分割します -
split2は:で、プレフィックスマッチによってキーを識別します -
この関数は、最初に一致したペアの
name:以降のすべてを返します
期待される出力:
+--------------+
| _c0 |
+--------------+
| zhangsan:man |
+--------------+
次のステップ
-
キーと値にデリミタが含まれていないキー値文字列を解析するには、「デリミタを含まない文字列の値を取得する」をご参照ください。
-
UDF 開発の詳細については、「Java UDF」および「Python 3 UDF」をご参照ください。