Pour répondre à la question du haut :
Fonction d'échappement d'expression régulière
Commençons par une liste complète des caractères ayant une signification particulière dans l'expression régulière motifs :
!$()*+.:<=>?[\]^{|}-
Enveloppés entre parenthèses, la plupart d'entre eux perdent leur signification particulière - à quelques exceptions près :
-
doit être le premier ou le dernier ou cela signifie une plage de caractères.]
et\
doivent être échappés avec\
(dans le remplacement, aussi).
Après avoir ajouté des parenthèses de capture pour la référence arrière ci-dessous, nous obtenons ce modèle d'expression régulière :
([!$()*+.:<=>?[\\\]^{|}-])
En l'utilisant, cette fonction échappe tous les caractères spéciaux avec une barre oblique inverse (\
) - supprimant ainsi la signification spéciale :
CREATE OR REPLACE FUNCTION f_regexp_escape(text)
RETURNS text
LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE AS
$func$
SELECT regexp_replace($1, '([!$()*+.:<=>?[\\\]^{|}-])', '\\\1', 'g')
$func$;
Ajouter PARALLEL SAFE
(parce que c'est c'est ) dans Postgres 10 ou version ultérieure pour permettre le parallélisme des requêtes qui l'utilisent.
Démo
SELECT f_regexp_escape('test(1) > Foo*');
Renvoie :
test\(1\) \> Foo\*
Et tandis que :
SELECT 'test(1) > Foo*' ~ 'test(1) > Foo*';
renvoie FALSE
, ce qui peut surprendre les utilisateurs naïfs,
SELECT 'test(1) > Foo*' ~ f_regexp_escape('test(1) > Foo*');
Renvoie TRUE
comme il se doit maintenant.
LIKE
fonction d'échappement
Pour être complet, le pendentif pour LIKE
modèles, où seuls trois caractères sont spéciaux :
\%_
Le manuel :
Le caractère d'échappement par défaut est la barre oblique inverse mais un autre peut être sélectionné en utilisant le
ESCAPE
clause.
Cette fonction assume la valeur par défaut :
CREATE OR REPLACE FUNCTION f_like_escape(text)
RETURNS text
LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE AS
$func$
SELECT replace(replace(replace($1
, '\', '\\') -- must come 1st
, '%', '\%')
, '_', '\_');
$func$;
Nous pourrions utiliser le plus élégant regexp_replace()
ici aussi, mais pour les quelques caractères, une cascade de replace()
fonctions est plus rapide.
Encore une fois, PARALLEL SAFE
dans Postgres 10 ou version ultérieure.
Démo
SELECT f_like_escape('20% \ 50% low_prices');
Renvoie :
20\% \\ 50\% low\_prices