Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

A expressão regular do Oracle com um hífen não fornece o mesmo resultado no Windows que no Unix


Como Avinash Raj disse nos comentários, o hífen em seu padrão de expressão regular está sendo interpretado como um intervalo. O comportamento parece ser dependente do algoritmo de ordenação utilizado pelos dois clientes, baseado na variável de ambiente NLS_LANG, que influencia o valor NLS_SORT.

Com 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

Arriscando porque seu perfil diz que você está no Marrocos, com 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

A razão é que o segmento padrão +-= é tratado como um intervalo que abrange todos os caracteres de + para = . No conjunto de caracteres ISO8859-1 e Windows 1252 que são os caracteres de 43 a 61, e todos os dígitos numéricos estão dentro desse intervalo - zero é 48, por exemplo - estão dentro desse intervalo, portanto, o regex os substitui. Isso também é verdade no conjunto de caracteres do Windows 1256 . (E qualquer coisa baseada em ASCII).

Mas seu NLS_LANG também está mudando implicitamente a ordem de classificação, e é mudar de classificação BINARY para ARABIC que altera o comportamento. Você pode ver isso em uma única sessão; com 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

Você também pode dizer que é um problema de intervalo modificando ligeiramente o intervalo; alterando +-= para +-3 portanto, os dígitos mais altos não são incluídos, mas deixando todo o resto igual:
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

Leia mais sobre classificação linguística .

Confiar nas configurações de NLS é sempre arriscado, portanto, é melhor evitar completamente o problema de intervalo alterando o padrão para ter o hífen no início ou no final, o que impede que ele seja visto como um intervalo; novamente como Avinash Raj sugeriu.