Zoals Avinash Raj in opmerkingen zei, wordt het koppelteken in je reguliere expressiepatroon geïnterpreteerd als een bereik. Het gedrag lijkt afhankelijk te zijn van het sorteeralgoritme dat door de twee clients wordt gebruikt, gebaseerd op de omgevingsvariabele NLS_LANG, die de NLS_SORT-waarde beïnvloedt.
Met 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
Op stap gaan terwijl je profiel zegt dat je in Marokko bent, met 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
De reden is dat het patroonsegment +-=
wordt behandeld als een bereik dat alle tekens van +
. omvat naar =
. In de ISO8859-1 en Windows 1252-tekenset
dat wil zeggen tekens 43 tot 61, en alle numerieke cijfers vallen binnen dat bereik - nul is bijvoorbeeld 48 - vallen binnen dat bereik, dus de regex vervangt ze. Dat geldt ook voor de Windows 1256-tekenset
. (En alles op basis van ASCII).
Maar je NLS_LANG verandert ook impliciet de sorteervolgorde, en het is de omschakeling van BINARY naar ARABISCHE sortering die het gedrag verandert. Dat zie je binnen één sessie; met 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
Je kunt ook zien dat het een bereikprobleem is door het bereik enigszins aan te passen; wijzigen van +-=
naar +-3
dus hogere cijfers zijn niet inbegrepen, maar de rest blijft hetzelfde:
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
Lees meer over taalkundige sortering .
Vertrouwen op NLS-instellingen is echter altijd riskant, dus het is beter om het bereikprobleem volledig te vermijden door het patroon te wijzigen om het koppelteken aan het begin of einde te hebben, waardoor het helemaal niet als een bereik wordt gezien; opnieuw zoals Avinash Raj suggereerde.