Para abordar la pregunta en la parte superior:
Función de escape de expresiones regulares
Comencemos con una lista completa de caracteres con significado especial en expresión regular patrones:
!$()*+.:<=>?[\]^{|}-
Envueltos en una expresión entre paréntesis, la mayoría de ellos pierden su significado especial, con algunas excepciones:
-
debe ser el primero o el último o significa un rango de personajes.]
y\
tiene que ser escapado con\
(en el reemplazo, también).
Después de agregar paréntesis de captura para la referencia posterior a continuación, obtenemos este patrón de expresión regular:
([!$()*+.:<=>?[\\\]^{|}-])
Usándolo, esta función escapa todos los caracteres especiales con una barra invertida (\
) - eliminando así el significado especial:
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$;
Agregar PARALLEL SAFE
(porque es ) en Postgres 10 o posterior para permitir el paralelismo de las consultas que lo utilizan.
Demostración
SELECT f_regexp_escape('test(1) > Foo*');
Devoluciones:
test\(1\) \> Foo\*
Y mientras:
SELECT 'test(1) > Foo*' ~ 'test(1) > Foo*';
devuelve FALSE
, que puede sorprender a los usuarios ingenuos,
SELECT 'test(1) > Foo*' ~ f_regexp_escape('test(1) > Foo*');
Devuelve TRUE
como debería ser ahora.
LIKE
función de escape
Para completar, el colgante para LIKE
patrones, donde solo tres caracteres son especiales:
\%_
El manual:
El carácter de escape predeterminado es la barra invertida, pero se puede seleccionar uno diferente usando ESCAPE
cláusula.
Esta función asume el valor predeterminado:
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$;
Podríamos usar el más elegante regexp_replace()
aquí también, pero para los pocos caracteres, una cascada de replace()
funciones es más rápido.
De nuevo, PARALLEL SAFE
en Postgres 10 o posterior.
Demostración
SELECT f_like_escape('20% \ 50% low_prices');
Devoluciones:
20\% \\ 50\% low\_prices