Untuk menjawab pertanyaan di atas:
Fungsi escape ekspresi reguler
Mari kita mulai dengan daftar lengkap karakter dengan arti khusus dalam ekspresi reguler pola:
!$()*+.:<=>?[\]^{|}-
Dibungkus dalam ekspresi kurung, sebagian besar kehilangan makna khusus - dengan beberapa pengecualian:
-harus menjadi yang pertama atau terakhir atau menandakan rentang karakter.]dan\harus di-escape dengan\(dalam penggantian juga).
Setelah menambahkan kurung penangkap untuk referensi belakang di bawah ini, kami mendapatkan pola regexp ini:
([!$()*+.:<=>?[\\\]^{|}-])
Dengan menggunakannya, fungsi ini lolos dari semua karakter khusus dengan garis miring terbalik (\ ) - dengan demikian menghilangkan arti khusus:
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$;
Tambahkan PARALLEL SAFE (karena adalah ) di Postgres 10 atau lebih baru untuk memungkinkan paralelisme kueri menggunakannya.
Demo
SELECT f_regexp_escape('test(1) > Foo*');
Pengembalian:
test\(1\) \> Foo\*
Dan sementara:
SELECT 'test(1) > Foo*' ~ 'test(1) > Foo*';
mengembalikan FALSE , yang mungkin mengejutkan bagi pengguna yang naif,
SELECT 'test(1) > Foo*' ~ f_regexp_escape('test(1) > Foo*');
Mengembalikan TRUE sebagaimana mestinya sekarang.
LIKE fungsi melarikan diri
Untuk kelengkapan, liontin untuk LIKE pola, di mana hanya tiga karakter yang spesial:
\%_
Panduan:
Karakter escape default adalah garis miring terbalik tetapi karakter lain dapat dipilih dengan menggunakan
ESCAPEklausa.
Fungsi ini mengasumsikan default:
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$;
Kita bisa menggunakan regexp_replace() yang lebih elegan di sini juga, tetapi untuk beberapa karakter, rangkaian replace() fungsi lebih cepat.
Sekali lagi, PARALLEL SAFE di Postgres 10 atau lebih baru.
Demo
SELECT f_like_escape('20% \ 50% low_prices');
Pengembalian:
20\% \\ 50\% low\_prices