IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

PL/SQL Oracle Discussion :

Split via Regexp


Sujet :

PL/SQL Oracle

  1. #1
    Futur Membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Juillet 2011
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Femme

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2011
    Messages : 4
    Par défaut Split via Regexp
    Bonjour a tous,

    Je cherche une moyen de splitter une chaine de caractères et comme l'intitulé l'indique avec des expressions régulières.
    Pour détailler tout ça, je passe en paramètre à une fonction stockée la chaine à découper ainsi qu'un délimiteur (là où la chaine doit être coupée), mon problème c'est que je ne sais pas comment utiliser les expressions dans ce sens là, vu que la chaine pourra comporter plusieurs occurrence du délimiteur et donc elle a une structure variable (on peut très bien avoir une chaine comme celle-ci : 'test01, test02' ou alors une comme ça : 'test01,test02,test03,..., testn')

    Voila je ne sais pas si j'ai été suffisamment clair pour tout le monde, si il manque des informations, je suis dispo

    Merci

  2. #2
    Membre Expert

    Homme Profil pro
    Inscrit en
    Mars 2010
    Messages
    536
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 536
    Par défaut
    Bonjour,

    Je suis justement en train de faire ce travail chez un client. J'ai pour cela créé deux fonctions une classique et une autre utilisant regexp.
    Je n'ai pas testé la seconde variante de la fonction, par contre j'ai bien testé la fonction classique et je pense que c'est elle que je vais devoir
    promouvoir dans les environnements de test, d'acceptation et de production. Avant de vous proposer le code, j'ai trois remarques dont vous devriez tenir
    compte:
    (1) Mon message commence par le séparateur
    (2) Vous n'êtes pas obligé d'utiliser un type table of varchar2(4000)
    (3) desolé pour l'anglais dans le texte du code (je n'ai fait que copier coller pour aller plus vite)

    Bien à vous

    (1) fonction classique
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
     
    mhouri.world > create or replace
      2  package split_text
      3  IS
      4  
      5   TYPE t_msg_array IS TABLE OF VARCHAR2(4000) INDEX BY BINARY_INTEGER;
      6  
      7    FUNCTION f_extract_message_info (piv_message IN VARCHAR2
      8                                    ,piv_delim   IN VARCHAR2)
      9       RETURN t_msg_array;
     10  
     11  END split_text;
     12  /
     
    Package created.
     
    mhouri.world > create or replace package body split_text
      2  IS
      3  
      4  FUNCTION f_extract_message_info (piv_message IN VARCHAR2
      5                                   ,piv_delim   IN VARCHAR2)
      6     RETURN t_msg_array
      7  IS
      8     l_t_msg_array   t_msg_array;
      9     ln_pos          NUMBER          := 0;
     10     li              INTEGER         := 0;
     11     lv_str          VARCHAR2 (4000) := piv_message;
     12  
     13  BEGIN
     14     -- Get the position fo the first delimitor
     15     ln_pos := instr(lv_str,piv_delim,1,1);
     16  
     17     -- While there is still delimitors loop
     18     WHILE ( ln_pos != 0)
     19     LOOP
     20  
     21       -- Remove the first delimitor from the message
     22       lv_str := substr(lv_str,ln_pos + length(piv_delim),length(lv_str));
     23  
     24       -- Determine now the new position of the first delimitor
     25       ln_pos := instr(lv_str,piv_delim,1,1);
     26  
     27       -- Fill each information of the message in an array
     28       li := li + 1;
     29       IF ln_pos != 0
     30       THEN
     31         l_t_msg_array(li) := substr(lv_str,1, ln_pos-1);
     32       ELSE
     33         l_t_msg_array(li) := lv_str;
     34       END IF;
     35  
     36     END LOOP;
     37  
     38     -- return the array
     39      RETURN l_t_msg_array;
     40  
     41  END f_extract_message_info;
     42  
     43  
     44  END split_text;
     45  /
     
    Package body created.
     
    mhouri.world > set serveroutput on
    mhouri.world > declare
      2   piv_txt            varchar2(4000);
      3   l_t_jus_msg_array  split_text.t_msg_array;
      4  
      5  BEGIN
      6  
      7   piv_txt := '#@test01#@test02#@test03';
      8  
      9   l_t_jus_msg_array     := split_text.f_extract_message_info(piv_txt,'#@');
     10  
     11   dbms_output.put_line(' item1 := '||l_t_jus_msg_array(1) );
     12   dbms_output.put_line(' item2 := '||l_t_jus_msg_array(2));
     13   dbms_output.put_line(' item3 := '||l_t_jus_msg_array(3));
     14  
     15  
     16  END;
     17  /
    item1 := test01                                                                 
    item2 := test02                                                                 
    item3 := test03                                                                 
     
    PL/SQL procedure successfully completed.
    (1) fonction avec regexp (pas suffisamment testée )

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
     
    mhouri.world > create or replace
      2  package split_text
      3  IS
      4  
      5   TYPE t_msg_array IS TABLE OF VARCHAR2(4000) INDEX BY BINARY_INTEGER;
      6  
      7  
      8    FUNCTION f_extract_message_info_regexp (piv_message IN VARCHAR2
      9                                            ,piv_delim   IN VARCHAR2)
     10       RETURN t_msg_array;
     11  
     12  
     13  END split_text;
     14  /
     
    Package created.
     
    mhouri.world > create or replace
      2  package body split_text
      3  IS
      4  
      5  FUNCTION f_extract_message_info_regexp (piv_message IN VARCHAR2
      6                                         ,piv_delim   IN VARCHAR2)
      7  /* ***************************************************************
      8   * Name     : f_extract_message_info                             *
      9   * Author   : Mohamed Houri                                      *
     10   * Abstract : it extracts tables fields from a payload message   *
     11   *****************************************************************/
     12     RETURN t_msg_array
     13  IS
     14     l_t_msg_array   t_msg_array;
     15     ln_pos          NUMBER          := 0;
     16     li              INTEGER         := 0;
     17     lv_str          VARCHAR2 (4000) := piv_message;
     18  
     19  BEGIN
     20     -- get the first position of the string
     21     ln_pos := INSTR (lv_str, piv_delim, 1, 1);
     22  
     23     WHILE (ln_pos != 0)
     24     LOOP
     25       -- Increment the array string counter
     26        li := li + 1;
     27  
     28       -- Create array element
     29        l_t_msg_array (li) := substr (regexp_substr (lv_str, '#@[^#@]*', 1, 1), 3);
     30  
     31       -- Remove from the original message the part of info that has been extracted
     32        lv_str := substr (lv_str, ln_pos + 1, length (lv_str));
     33  
     34        -- Determine the new position of first delimiter in the string
     35        ln_pos := instr (lv_str, piv_delim, 1, 1);
     36  
     37     END LOOP;
     38  
     39     RETURN l_t_msg_array;
     40  END f_extract_message_info_regexp;
     41  
     42  END split_text;
     43  /
     
    Package body created.
     
    mhouri.world > declare
      2   piv_txt            varchar2(4000);
      3   l_t_jus_msg_array  split_text.t_msg_array;
      4  
      5  BEGIN
      6  
      7   piv_txt := '#@test01#@test02#@test03';
      8  
      9   l_t_jus_msg_array     := split_text.f_extract_message_info_regexp(piv_txt,'#@');
     10  
     11   dbms_output.put_line(' item1 := '||l_t_jus_msg_array(1) );
     12   dbms_output.put_line(' item2 := '||l_t_jus_msg_array(2));
     13   dbms_output.put_line(' item3 := '||l_t_jus_msg_array(3));
     14  
     15  
     16  END;
     17  /
    item1 := test01                                                                 
    item2 := test02                                                                 
    item3 := test03                                                                 
     
    PL/SQL procedure successfully completed.
    Bien Cordialement

    Mohamed Houri

  3. #3
    Futur Membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Juillet 2011
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Femme

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2011
    Messages : 4
    Par défaut
    Ok, merci je vais tester ça (la partie avec des regexp) l'autre m'intéresse moins vu que je l'ai déjà faite de mon côté mais par souci d'optimisation je préfère utiliser des expressions régulières.

    Je repasserai dès que j'aurai adapté ça à mon travail

  4. #4
    Futur Membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Juillet 2011
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Femme

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2011
    Messages : 4
    Par défaut
    Alors voila ce que ça donne pour moi, bon ça ne remplit pas tout à fait ce que je veux faire en complet mais ça couvre une partie.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     
        ln_pos := INSTR (chaine_parcour, delimiter);
        WHILE (ln_pos != 0)
          LOOP
     
            -- Create array element
             table_reg(table_reg.count + 1).nom := substr (regexp_substr (chaine_parcour,'[^' || delimiter || ']*' || delimiter, 1, 1), 0,ln_pos - 1);
     
            -- Remove from the original message the part of info that has been extracted
             chaine_parcour := substr (chaine_parcour, ln_pos + 1, length (chaine_parcour));
     
             -- Determine the new position of first delimiter in the string
             ln_pos := instr (chaine_parcour, delimiter, 1, 1);
     
          END LOOP;
     
         If ln_pos = 0 then
     
             table_reg(table_reg.count + 1).nom := substr (regexp_substr (chaine_parcour,'[^' || delimiter || ']*$'  , 1, 1), 2);
     
         End if;
    Ma chaine à découper étant différente de la tienne, j'ai donc adapté à ma "sauce", maintenant il faut que j'ajoute une fonction qui fasse presque la même chose.
    Il me faut une nouvelle fois découper une chaine mais qui sera sous cette forme : 'test01 a, test02 b, ...' en séparant au niveau de chaque espace, ce n'est pas bien compliqué puisque j'ai déjà la séparation au niveau des virgules !

    Merci l'ami de m'avoir aider

Discussions similaires

  1. remplacements via regexp
    Par sluke dans le forum Général Python
    Réponses: 6
    Dernier message: 09/09/2011, 11h27
  2. [RegExp] split sur regexp non capturant
    Par SpaceFrog dans le forum Général JavaScript
    Réponses: 6
    Dernier message: 27/05/2010, 10h16
  3. Suppression de caractère via RegExp
    Par totoche dans le forum Vos contributions VB6
    Réponses: 1
    Dernier message: 29/12/2008, 13h01
  4. [RegExp]Split chaîne par espaces sauf ceux entre guillemets ?
    Par Loic Desjardins dans le forum Langage
    Réponses: 2
    Dernier message: 17/11/2006, 10h33
  5. [MySQL] recherche de mots via REGEXP : problème d'accents
    Par matperino dans le forum PHP & Base de données
    Réponses: 2
    Dernier message: 30/10/2006, 21h48

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo