För att svara på frågan överst:
Escape-funktion för reguljära uttryck
Låt oss börja med en komplett lista över tecken med speciell betydelse i reguljära uttryck mönster:
!$()*+.:<=>?[\]^{|}-
Insvept i ett parentes uttryck förlorar de flesta av dem sin speciella betydelse - med några få undantag:
-
måste vara först eller sist, annars betyder det ett intervall tecken.]
och\
måste escapes med\
(även i ersättningen).
Efter att ha lagt till fångande parenteser för bakre referens nedan får vi detta regexp-mönster:
([!$()*+.:<=>?[\\\]^{|}-])
Med den här funktionen undkommer alla specialtecken med ett snedstreck (\
) - tar därmed bort den speciella betydelsen:
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$;
Lägg till PARALLEL SAFE
(eftersom det är ) i Postgres 10 eller senare för att tillåta parallellitet för frågor som använder den.
Demo
SELECT f_regexp_escape('test(1) > Foo*');
Returnerar:
test\(1\) \> Foo\*
Och medan:
SELECT 'test(1) > Foo*' ~ 'test(1) > Foo*';
returnerar FALSE
, vilket kan komma som en överraskning för naiva användare,
SELECT 'test(1) > Foo*' ~ f_regexp_escape('test(1) > Foo*');
Returnerar TRUE
som det ska nu.
LIKE
flyktfunktion
För fullständighetens skull, hängsmycken för LIKE
mönster, där endast tre tecken är speciella:
\%_
Manualen:
Standardtecknet för escape är omvänt snedstreck men ett annat kan väljas genom att använda
ESCAPE
klausul.
Den här funktionen antar standard:
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 skulle kunna använda den mer eleganta regexp_replace()
även här, men för de få tecknen, en kaskad av replace()
funktioner är snabbare.
Återigen, PARALLEL SAFE
i Postgres 10 eller senare.
Demo
SELECT f_like_escape('20% \ 50% low_prices');
Returnerar:
20\% \\ 50\% low\_prices