Contrairement à la fonction intégrée REGEXP_REPLACE, une fonction définie par l'utilisateur (UDF) vous permet d'utiliser des variables dans une expression régulière. Cette rubrique explique comment mettre en œuvre une UDF UDF_REPLACE_BY_REGEXP en Java ou en Python qui accepte le motif regex comme argument.
Signature de la UDF
Syntaxe :
string UDF_REPLACE_BY_REGEXP(string <s>, string <regex>, string <replacement>)
Paramètres :
Les trois paramètres sont obligatoires et acceptent des valeurs STRING.
| Paramètre | description |
|---|---|
s |
La chaîne source |
regex |
L'expression régulière à faire correspondre avec s |
replacement |
La chaîne qui remplace chaque occurrence trouvée |
Valeur de retour : STRING
Prérequis
Avant de commencer, assurez-vous que vous disposez des éléments suivants :
Un projet MaxCompute avec les permissions de développement UDF
Un environnement de développement Java ou Python
Étape 1 : Écrire la UDF
Choisissez Java ou Python en fonction de votre environnement de développement.
UDF Java
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();
}
}
Une UDF Java doit étendre la classe UDF. La signature de la méthode evaluate — trois paramètres d'entrée STRING et une valeur de retour STRING — définit la signature de la UDF dans les instructions SQL. Pour connaître toutes les spécifications des UDF Java, consultez la rubrique Java UDFs.
UDF Python 3
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
Par défaut, les projets MaxCompute exécutent les UDF avec Python 2. Pour utiliser Python 3, exécutez set odps.sql.python.version=cp37 au niveau de la session avant d'appeler la UDF. Pour connaître toutes les spécifications des UDF Python 3, consultez la rubrique Python 3 UDFs.
UDF Python 2
#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
Si votre code UDF Python 2 contient des caractères chinois, ajoutez une déclaration d'encodage en haut du fichier. Les déclarations #coding:utf-8 et # -*- coding: utf-8 -*- sont toutes deux valides. Pour connaître toutes les spécifications des UDF Python 2, consultez la rubrique Python 2 UDFs.
Étape 2 : Charger les ressources et enregistrer la UDF
Après avoir écrit et testé votre code UDF, chargez-le sur MaxCompute et enregistrez-le sous le nom UDF_REPLACE_BY_REGEXP.
Java : Consultez la rubrique Package a Java program, upload the package, and create a MaxCompute UDF.
Python : Consultez la rubrique Upload a Python program and create a MaxCompute UDF.
Étape 3 : Utiliser la UDF
Exécutez le code SQL suivant pour remplacer toutes les séquences de chiffres dans une chaîne par # :
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+', '#');
Sortie attendue :
+--------------+
| _c0 |
+--------------+
| abc # def # |
+--------------+
Étapes suivantes
Java UDFs — Spécifications et exigences des UDF Java
Python 3 UDFs — Spécifications des UDF Python 3
Python 2 UDFs — Spécifications des UDF Python 2