Jak powiedział Avinash Raj w komentarzach, myślnik we wzorcu wyrażenia regularnego jest interpretowany jako zakres. To zachowanie wydaje się być zależne od algorytmu sortowania używanego przez dwóch klientów, w oparciu o zmienną środowiskową NLS_LANG, która wpływa na wartość NLS_SORT.
Z 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
Wychodzenie na kończynę, gdy Twój profil mówi, że jesteś w Maroku, z 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
Powodem jest to, że segment wzorca +-=
jest traktowany jako zakres obejmujący wszystkie znaki z +
do =
. W ISO8859-1 i zestaw znaków Windows 1252
to znaczy znaki od 43 do 61, a wszystkie cyfry mieszczą się w tym zakresie – na przykład zero to 48 – są w tym zakresie, więc wyrażenie regularne je zastępuje. Dotyczy to również zestawu znaków Windows 1256
. (I wszystko oparte na ASCII).
Ale twój NLS_LANG również niejawnie zmienia porządek sortowania i przełącza z sortowania BINARNEGO na ARABSKIEGO, co zmienia zachowanie. Możesz to zobaczyć podczas jednej sesji; z 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
Możesz również stwierdzić, że jest to problem z zakresem, nieznacznie modyfikując zakres; zmiana +-=
do +-3
więc wyższe cyfry nie są uwzględniane, ale wszystko inne pozostaje bez zmian:
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
Przeczytaj więcej o sortowaniu językowym .
Poleganie na ustawieniach NLS jest jednak zawsze ryzykowne, więc lepiej całkowicie uniknąć problemu z zasięgiem, zmieniając wzór tak, aby miał myślnik na początku lub na końcu, co w ogóle nie pozwala na postrzeganie go jako zakresu; ponownie, jak zasugerował Avinash Raj.