For at besvare spørgsmålet øverst:
Escape-funktion for regulære udtryk
Lad os starte med en komplet liste over tegn med særlig betydning i regulære udtryk mønstre:
!$()*+.:<=>?[\]^{|}-
Indpakket i et parentes-udtryk mister de fleste af dem deres særlige betydning - med nogle få undtagelser:
-
skal være først eller sidst, eller det betyder et interval af tegn.]
og\
skal escapes med\
(også i erstatningen).
Efter tilføjelse af indfangende parenteser til bagsiden nedenfor får vi dette regexp-mønster:
([!$()*+.:<=>?[\\\]^{|}-])
Ved at bruge den undslipper denne funktion alle specialtegn med en omvendt skråstreg (\
) - derved fjernes den særlige betydning:
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$;
Tilføj PARALLEL SAFE
(fordi det er ) i Postgres 10 eller nyere for at tillade parallelitet for forespørgsler, der bruger det.
Demo
SELECT f_regexp_escape('test(1) > Foo*');
Returnerer:
test\(1\) \> Foo\*
Og mens:
SELECT 'test(1) > Foo*' ~ 'test(1) > Foo*';
returnerer FALSE
, hvilket kan komme som en overraskelse for naive brugere,
SELECT 'test(1) > Foo*' ~ f_regexp_escape('test(1) > Foo*');
Returnerer TRUE
som det skal nu.
LIKE
escape-funktion
For fuldstændighedens skyld, vedhænget til LIKE
mønstre, hvor kun tre tegn er specielle:
\%_
Manualen:
Standard escape-tegn er omvendt skråstreg, men en anden kan vælges ved at bruge ESCAPE
klausul.
Denne funktion antager standarden:
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$;
Vi kunne bruge den mere elegante regexp_replace()
også her, men for de få tegn, en kaskade af replace()
funktioner er hurtigere.
Igen, PARALLEL SAFE
i Postgres 10 eller senere.
Demo
SELECT f_like_escape('20% \ 50% low_prices');
Returnerer:
20\% \\ 50\% low\_prices