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
ESCAPE
klausa.
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