Để giải quyết câu hỏi ở đầu:
Hàm thoát biểu thức chính quy
Hãy bắt đầu với danh sách đầy đủ các ký tự có ý nghĩa đặc biệt trong biểu thức chính quy mẫu:
!$()*+.:<=>?[\]^{|}-
Được bao bọc trong một biểu thức dấu ngoặc, hầu hết chúng đều mất đi ý nghĩa đặc biệt - với một số ngoại lệ:
-
-
cần phải đứng đầu hoặc cuối cùng hoặc nó biểu thị một phạm vi của các ký tự. -
]
và\
phải được thoát bằng\
(thay thế luôn).
Sau khi thêm dấu ngoặc đơn cho tham chiếu phía sau, chúng tôi nhận được mẫu regexp này:
([!$()*+.:<=>?[\\\]^{|}-])
Khi sử dụng nó, hàm này sẽ loại bỏ tất cả các ký tự đặc biệt bằng dấu gạch chéo ngược (\
) - do đó loại bỏ ý nghĩa đặc biệt:
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$;
Thêm PARALLEL SAFE
(bởi vì nó là ) trong Postgres 10 trở lên để cho phép truy vấn song song các truy vấn sử dụng nó.
Bản trình diễn
SELECT f_regexp_escape('test(1) > Foo*');
Lợi nhuận:
test\(1\) \> Foo\*
Và trong khi:
SELECT 'test(1) > Foo*' ~ 'test(1) > Foo*';
trả về FALSE
, điều này có thể gây ngạc nhiên cho những người dùng ngây thơ,
SELECT 'test(1) > Foo*' ~ f_regexp_escape('test(1) > Foo*');
Trả về TRUE
như bây giờ.
LIKE
chức năng thoát
Để hoàn thiện, mặt dây chuyền cho LIKE
mẫu, trong đó chỉ có ba ký tự là đặc biệt:
\%_
Hướng dẫn sử dụng:
Ký tự thoát mặc định là dấu gạch chéo ngược nhưng có thể chọn một ký tự khác bằng cách sử dụng
ESCAPE
mệnh đề.
Hàm này giả định giá trị mặc định:
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$;
Chúng tôi có thể sử dụng regexp_replace()
thanh lịch hơn ở đây cũng vậy, nhưng đối với một vài ký tự, một loạt các replace()
các chức năng nhanh hơn.
Xin nhắc lại, PARALLEL SAFE
trong Postgres 10 trở lên.
Bản trình diễn
SELECT f_like_escape('20% \ 50% low_prices');
Lợi nhuận:
20\% \\ 50\% low\_prices