Như Avinash Raj đã nói trong phần bình luận, dấu gạch nối trong mẫu biểu thức chính quy của bạn đang được hiểu là một phạm vi. Hành vi dường như phụ thuộc vào thuật toán sắp xếp đang được sử dụng bởi hai ứng dụng khách, dựa trên biến môi trường NLS_LANG, biến môi trường ảnh hưởng đến giá trị NLS_SORT.
Với NLS_LANG=ENGLISH_UNITED KINGDOM.WE8ISO8859P1
:
SQL> select REGEXP_REPLACE ('TEST 3304 V2', '[`[email protected]#$%^&*()_+-={}|;.:<>?,./]', ' ') as REG from dual;
REG
------------
TEST V
SQL> select value from nls_session_parameters where parameter = 'NLS_SORT';
VALUE
----------
BINARY
Đi chơi với một chi phí nhỏ khi hồ sơ của bạn cho biết bạn đang ở Maroc, với NLS_LANG="ARABIC_MOROCCO.AR8MSWIN1256"
:
SQL> select REGEXP_REPLACE ('TEST 3304 V2', '[`[email protected]#$%^&*()_+-={}|;.:<>?,./]', ' ') as REG from dual;
REG
------------
TEST 3304 V2
SQL> select value from nls_session_parameters where parameter = 'NLS_SORT';
VALUE
----------
ARABIC
Lý do là đoạn mẫu +-=
được coi là một dải ô bao gồm tất cả các ký tự từ +
thành =
. Trong ISO8859-1 và bộ ký tự Windows 1252
đó là các ký tự từ 43 đến 61 và tất cả các chữ số nằm trong phạm vi đó - ví dụ:số 0 là 48 - đều nằm trong phạm vi đó, vì vậy regex sẽ thay thế chúng. Điều đó cũng đúng trong bộ ký tự Windows 1256
. (Và bất kỳ thứ gì dựa trên ASCII).
Nhưng NLS_LANG của bạn cũng đang hoàn toàn thay đổi thứ tự sắp xếp và việc chuyển từ sắp xếp BINARY sang ARABIC sẽ thay đổi hành vi. Bạn có thể thấy điều đó trong một phiên duy nhất; với NLS_LANG=ENGLISH_UNITED KINGDOM.WE8ISO8859P1
:
SQL> select REGEXP_REPLACE ('TEST 3304 V2', '[`[email protected]#$%^&*()_+-={}|;.:<>?,./]', ' ') as REG from dual;
REG
------------
TEST V
SQL> alter session set NLS_SORT=ARABIC;
Session altered.
SQL> select REGEXP_REPLACE ('TEST 3304 V2', '[`[email protected]#$%^&*()_+-={}|;.:<>?,./]', ' ') as REG from dual;
REG
------------
TEST 3304 V2
Bạn cũng có thể biết rằng đó là một vấn đề về phạm vi bằng cách sửa đổi một chút phạm vi; thay đổi +-=
thành +-3
vì vậy các chữ số cao hơn không được bao gồm, nhưng giữ nguyên mọi thứ khác:
SQL> alter session set NLS_SORT=BINARY;
Session altered.
SQL> select REGEXP_REPLACE ('TEST 3304 V2', '[`[email protected]#$%^&*()_+-3{}|;.:<>?,./]', ' ') as REG from dual;
REG
------------
TEST 4 V
Đọc thêm về sắp xếp theo ngôn ngữ .
Mặc dù vậy, việc dựa vào cài đặt NLS luôn có rủi ro, vì vậy tốt hơn hết bạn nên tránh hoàn toàn vấn đề về phạm vi bằng cách thay đổi mẫu để có dấu gạch ngang ở đầu hoặc cuối, điều này khiến nó không bị coi là một phạm vi; một lần nữa như Avinash Raj đã đề xuất.