Yerleşik REGEXP_REPLACE işlevine kıyasla kullanıcı tanımlı bir işlev (UDF), düzenli ifadelerde değişkenler kullanmanıza olanak tanır. Bu konu, regex desenini bağımsız değişken olarak kabul eden bir UDF_REPLACE_BY_REGEXP UDF'sinin Java veya Python'da nasıl uygulanacağını gösterir.
UDF imzası
Sözdizimi:
string UDF_REPLACE_BY_REGEXP(string <s>, string <regex>, string <replacement>)
Parametreler:
Üç parametrenin tümü zorunludur ve STRING değerleri kabul eder.
| Parametre | Açıklama |
|---|---|
s |
Kaynak dize |
regex |
s ile eşleştirilecek düzenli ifade |
replacement |
Her eşleşmeyi değiştiren dize |
Dönüş değeri: STRING
Önkoşullar
Başlamadan önce şunlara sahip olduğunuzdan emin olun:
UDF geliştirme izinlerine sahip bir MaxCompute projesi
Bir Java veya Python geliştirme ortamı
1. Adım: UDF'yi yazma
Geliştirme ortamınıza bağlı olarak Java veya Python'u seçin.
Java UDF
package com.aliyun.rewrite; // Specify a package name.
import com.aliyun.odps.udf.UDF;
import com.aliyun.odps.udf.annotation.UdfProperty;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@UdfProperty(isDeterministic=true)
public class ReplaceByRegExp extends UDF {
/**
* The regular expression in the most recent query, which is cached to avoid multiple compilations.
*/
private String lastRegex = "";
private Pattern pattern = null;
/**
* @param s The source string.
* @param regex The regular expression.
* @param replacement The string that replaces the source string.
*/
public String evaluate(String s, String regex, String replacement) {
Objects.requireNonNull(s, "The source string cannot be null");
Objects.requireNonNull(regex, "The regular expression cannot be null");
Objects.requireNonNull(replacement, "The string that replaces the source string cannot be null");
// If the regular expression is changed, recompile the regular expression.
if (!regex.equals(lastRegex)) {
lastRegex = regex;
pattern = Pattern.compile(regex);
}
Matcher m = pattern.matcher(s);
StringBuffer sb = new StringBuffer();
// Perform text replacement.
while (m.find()) {
m.appendReplacement(sb, replacement);
}
m.appendTail(sb);
return sb.toString();
}
}
Bir Java UDF'si, UDF sınıfından türemelidir. evaluate yöntemi imzası — üç STRING giriş parametresi ve bir STRING dönüş değeri — SQL deyimlerinde UDF'nin imzasını tanımlar. Tam Java UDF teknik özellikleri için bkz. Java UDFs.
Python 3 UDF
from odps.udf import annotate
import re
@annotate("string,string,string->string")
class ReplaceByRegExp(object):
def __init__(self):
self.lastRegex = ""
self.pattern = None
def evaluate(self, s, regex, replacement):
if not s or not regex or not replacement:
raise ValueError("Arguments with None")
# If the regular expression is changed, recompile the regular expression.
if regex != self.lastRegex:
self.lastRegex = regex
self.pattern = re.compile(regex)
result = self.pattern.sub(replacement, s)
return result
MaxCompute projeleri varsayılan olarak UDF'leri Python 2 ile çalıştırır. Python 3'ü kullanmak için UDF'yi çağırmadan önce oturum düzeyinde set odps.sql.python.version=cp37 komutunu çalıştırın. Tam Python 3 UDF teknik özellikleri için bkz. Python 3 UDFs.
Python 2 UDF
#coding:utf-8
from odps.udf import annotate
import re
@annotate("string,string,string->string")
class ReplaceByRegExp(object):
def __init__(self):
self.lastRegex = ""
self.pattern = None
def evaluate(self, s, regex, replacement):
if not s or not regex or not replacement:
raise ValueError("Arguments with None")
# If the regular expression is changed, recompile the regular expression.
if regex != self.lastRegex:
self.lastRegex = regex
self.pattern = re.compile(regex)
result = self.pattern.sub(replacement, s)
return result
Python 2 UDF kodunuz Çince karakterler içeriyorsa dosyanın en üstüne bir kodlama bildirimi ekleyin. Hem #coding:utf-8 hem de # -*- coding: utf-8 -*- geçerlidir. Tam Python 2 UDF teknik özellikleri için bkz. Python 2 UDFs.
2. Adım: Kaynakları yükleme ve UDF'yi kaydetme
UDF kodunuzu yazıp test ettikten sonra MaxCompute'e yükleyin ve UDF_REPLACE_BY_REGEXP olarak kaydedin.
3. Adım: UDF'yi kullanma
Bir dizedeki tüm rakam dizilerini # ile değiştirmek için aşağıdaki SQL'i çalıştırın:
set odps.sql.python.version=cp37; -- To use a UDF in Python 3, run this command.
SELECT UDF_REPLACE_BY_REGEXP('abc 123 def 456', '\\d+', '#');
Beklenen çıktı:
+--------------+
| _c0 |
+--------------+
| abc # def # |
+--------------+
Sonraki adımlar
Java UDFs — Java UDF teknik özellikleri ve gereksinimleri
Python 3 UDFs — Python 3 UDF teknik özellikleri
Python 2 UDFs — Python 2 UDF teknik özellikleri