PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Escape-Funktion für reguläre Ausdrücke oder LIKE-Muster

Um die Frage ganz oben zu beantworten:

Escape-Funktion für reguläre Ausdrücke

Beginnen wir mit einer vollständigen Liste von Zeichen mit besonderer Bedeutung in regulären Ausdrücken Muster:

!$()*+.:<=>?[\]^{|}-

Eingehüllt in einen Klammerausdruck verlieren die meisten ihre besondere Bedeutung - mit wenigen Ausnahmen:

  • - muss an erster oder letzter Stelle stehen oder gibt einen Bereich an von Zeichen.
  • ] und \ müssen mit \ maskiert werden (auch im Ersatz).

Nach dem Hinzufügen von einfangenden Klammern für die Rückreferenz unten erhalten wir dieses Regexp-Muster:

([!$()*+.:<=>?[\\\]^{|}-])

Damit maskiert diese Funktion alle Sonderzeichen mit einem Backslash (\ ) - wodurch die besondere Bedeutung entfällt:

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$;

Fügen Sie PARALLEL SAFE hinzu (weil es ist ) in Postgres 10 oder höher, um Parallelität für Abfragen zu ermöglichen, die es verwenden.

Demo

SELECT f_regexp_escape('test(1) > Foo*');

Rückgabe:

test\(1\) \> Foo\*

Und dabei:

SELECT 'test(1) > Foo*' ~ 'test(1) > Foo*';

gibt FALSE zurück , was naive Benutzer überraschen mag,

SELECT 'test(1) > Foo*' ~ f_regexp_escape('test(1) > Foo*');

Gibt TRUE zurück wie es jetzt sein sollte.

LIKE Escape-Funktion

Der Vollständigkeit halber das Pendant für LIKE Muster, bei denen nur drei Zeichen besonders sind:

\%_

Das Handbuch:

Das Standard-Escape-Zeichen ist der Backslash, aber mit ESCAPE kann ein anderes gewählt werden Klausel.

Diese Funktion nimmt den Standard an:

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$;

Wir könnten das elegantere regexp_replace() verwenden auch hier, bis auf die wenigen Zeichen, eine Kaskade von replace() Funktionen ist schneller.

Nochmals, PARALLEL SAFE in Postgres 10 oder höher.

Demo

SELECT f_like_escape('20% \ 50% low_prices');

Rückgabe:

20\% \\ 50\% low\_prices