2011-09-27 50 views
23

Tôi đang gặp sự cố với các ranh giới công việc phù hợp với REGEXP_LIKE. Truy vấn sau trả về một hàng duy nhất, như mong đợi.Oracle REGEXP_LIKE và các ranh giới từ

select 1 from dual 
where regexp_like('DOES TEST WORK HERE','TEST'); 

Nhưng tôi cũng muốn khớp với ranh giới từ. Vì vậy, việc thêm ký tự "\ b" cung cấp truy vấn này

select 1 from dual 
where regexp_like('DOES TEST WORK HERE','\bTEST\b'); 

Chạy hàng này trả về 0 hàng. Bất kỳ ý tưởng?

+0

Đó là lạ. Tôi không thể làm cho nó hoạt động, hoặc là ... Ví dụ, 'chọn regexp_replace ('DOES TEST WORK HERE', '\ bTEST \ b', 'X') từ kép;' trả về 'DOES TEST WORK HERE'. .. Nó hoạt động nếu bạn sử dụng '\ W', nhưng nó không giống như' \ b': P – Xophmeister

Trả lời

35

Tôi tin rằng bạn muốn thử

select 1 from dual 
    where regexp_like ('does test work here', '(^|\s)test(\s|$)'); 

\b không xuất hiện trong danh sách này: http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14251/adfns_regexp.htm#i1007670

Các \s đảm bảo rằng bắt đầu thử nghiệm và kết thúc bằng một khoảng trắng. Điều này là không đủ, tuy nhiên, vì chuỗi test cũng có thể xuất hiện ở đầu hoặc cuối của chuỗi được khớp. Do đó, tôi sử dụng cách thay thế (được chỉ định bởi |) ^ để bắt đầu chuỗi và $ cho kết thúc chuỗi.

Update (sau 3 năm +) ... Vì nó xảy ra, tôi cần chức năng này ngày hôm nay, và nó xuất hiện với tôi, mà thậm chí còn tốt một biểu thức chính quy là (^|\s|\W)test($|\s|\W) (The missing \b regular expression special character in Oracle).

+0

Cảm ơn vì điều đó. Tôi tìm thấy rất nhiều tài nguyên trên mạng (ví dụ: http://psoug.org/snippet/Regular-Expressions--Regexp-Cheat-Sheet_856.htm) đề xuất bạn có thể. Tôi thực sự muốn khớp với phần đầu hoặc phần cuối của một chuỗi hoặc một ký tự "không phải chữ" trong trường hợp của tôi - vì vậy tôi đã chuyển \ W vào vị trí của \ s. –

+0

Có, có vẻ như Oracle đã chọn không hỗ trợ '\ b' mặc dù đây là một mã thông báo biểu thức chính quy khá chuẩn. –

+0

Biểu thức chính quy của Oracle sử dụng chuẩn POSIX ERE (với một số cải tiến như backreferences) không hỗ trợ các ranh giới từ. –

0

Nói chung, tôi sẽ gắn bó với giải pháp của René, ngoại lệ là khi bạn cần khớp với độ dài bằng 0. tức là Bạn không muốn thực sự nắm bắt ký tự không phải từ ở đầu/cuối. Ví dụ, nếu chuỗi của chúng tôi là test test thì (\b)test(\b) sẽ khớp hai lần nhưng (^|\s|\W)test($|\s|\W) sẽ chỉ khớp với lần xuất hiện đầu tiên. Ít nhất, đó chắc chắn là trường hợp nếu bạn cố gắng sử dụng regexp_substr.

Ví dụ

SELECT regexp_substr('test test', '(^|\s|\W)test($|\s|\W)', 1, 1, 'i'), regexp_substr('test test', '(^|\s|\W)test($|\s|\W)', 1, 2, 'i') FROM dual;

Returns

test |NULL

Các vấn đề liên quan