sql >> Databasteknik >  >> RDS >> PostgreSQL

Escape-funktion för reguljära uttryck eller LIKE-mönster

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


  1. En guide för att förstå databasskalningsmönster

  2. Hur trunkerar man alla tabeller i en databas med TSQL?

  3. När skulle du använda en tabellvärderad funktion?

  4. Hur man uppdaterar primärnyckeln