2017-05-03 3 views
1

Malheureusement, le caractère d'expression régulière \b ne fonctionne pas dans Oracle. b caractère d'expression régulière dans Oracle 11g

Pour contourner ce problème, je trouve l'expression suivante:

(^|\s|\W)(100100|100101|100102|100103)($|\s|\W) 

(voir: The missing \b regular expression special character in Oracle.), mais dans les données de chaîne de test:

Test string 100100/100101, ABC-DEF, 100102 100103 test data abc100100 100100abc. 

valeurs 100101 et 100103 ne sont pas couvertes, alors que je suis s'attendant à ce qu'ils soient appariés comme c'est le cas de l'expression \b.

Y at-il un moyen de le faire fonctionner? J'utilise Oracle 11g.

Je serais apprécié pour toute aide.

EDIT:

Mon but est de marquer tous les matches. La sortie que je me attends est:

Test string [ddd]100100[/ddd]/[ddd]100101[/ddd], ABC-DEF, [ddd]100102[/ddd] [ddd]100103[/ddd] test data abc100100 100100abc. 

Dans ce but, je me sers déclaration suivante:

regexp_replace(p_text,'(^|\s|\W)(' || l_ids || ')($|\s|\W)', '\1[ddd]\2[/ddd]\3'); 

Où:

  • l_ids - liste des ids séparés par |, id peut contenir le nombre, les lettres, les traits de soulignement et les tirets
  • p_text - saisir le texte

EDIT 2:

Dans la valeur de chaîne de test ci-dessus 100100 ne doit pas correspondre au mot abc100100 ainsi que 100100abc.

+0

voulez-vous produire des correspondances sur différentes lignes? –

+0

La seconde '(^ | \ s | \ W)' devrait être '($ | \ s | \ W)'. De plus '\ s' est déjà inclus dans' \ W'. Notez que le '/' suivant le premier nombre est consommé par le premier motif et ne peut donc pas être utilisé pour la deuxième correspondance, il est difficile de contourner ce problème sans les retards. –

+0

@vkp s'il vous plaît voir mon edit dans la question. – kpater87

Répondre

0

En supposant -

  • chr(1) ne figure pas dans le texte
  • Tout caractère qui n'est pas [a-zA-Z0-9] est considéré comme un séparateur (par exemple /)

with t (p_text) as (select 'Test string 100100/100101, ABC-DEF, 100102 100103 test data abc100100 100100abc.' from dual) 

select replace 
     (
      regexp_replace 
      (
       regexp_replace 
       (
        p_text 
        ,'([a-zA-Z0-9]+)' 
        ,chr(1) || '\1' || chr(1) 
       ) 
       ,chr(1) || '(100100|100101|100102|100103)' || chr(1) 
       ,'[ddd]\1[/ddd]' 
      ) 
      ,chr(1) 
     ) 

from t 

T est chaîne [ddd] 100100 [/ ddd]/[ddd] 100101 [/ ddd], ABC-DEF, [ddd] 100102 [/ ddd] [ddd] 100103 [/ ddd] données de test abc100100 100100abc.

+0

Oui, ça marche ! Mais il y a un problème ici. Cela ne fonctionnera pas pour les longues chaînes d'entrée. Mes tests montrent que le premier 'REGEXP_REPLACE' coupe la sortie à 4000 octets (ce que je comprends). Mais la seconde 'REGEXP_REPLACE' coupe la sortie à environ 1800 octets et c'est ce que je ne comprends pas ... Mais en utilisant PL/SQL je peux contourner ce problème. Je vous remercie. – kpater87