Oracle
 sql >> Base de données >  >> RDS >> Oracle

L'expression régulière Oracle ayant un trait d'union ne donne pas le même résultat sous Windows que sous Unix

Comme Avinash Raj l'a dit dans les commentaires, le trait d'union dans votre modèle d'expression régulière est interprété comme une plage. Le comportement semble dépendre de l'algorithme de tri utilisé par les deux clients, basé sur la variable d'environnement NLS_LANG, qui influence la valeur NLS_SORT.

Avec 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

Sortir sur une branche alors que votre profil indique que vous êtes au Maroc, avec 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

La raison est que le segment de motif +-= est traité comme une plage couvrant tous les caractères de + à = . Dans le jeu de caractères ISO8859-1 et Windows 1252 c'est-à-dire les caractères 43 à 61, et tous les chiffres numériques entrent dans cette plage - zéro est 48 par exemple - sont dans cette plage, donc la regex les remplace. Cela est également vrai dans le jeu de caractères Windows 1256 . (Et tout ce qui est basé sur ASCII).

Mais votre NLS_LANG change également implicitement l'ordre de tri, et c'est le passage du tri BINARY au tri ARABIC qui change le comportement. Vous pouvez le voir en une seule session ; avec 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

Vous pouvez également dire qu'il s'agit d'un problème de plage en modifiant légèrement la plage ; changer +-= à +-3 donc les chiffres supérieurs ne sont pas inclus, mais en laissant tout le reste pareil :

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

En savoir plus sur le tri linguistique .

Cependant, s'appuyer sur les paramètres NLS est toujours risqué, il est donc préférable d'éviter complètement le problème de plage en modifiant le modèle pour avoir le trait d'union au début ou à la fin, ce qui l'empêche d'être considéré comme une plage du tout; à nouveau comme l'a suggéré Avinash Raj.